+++ /dev/null
-/*
- Copyright (C) 2001-2006, William Joseph.
- All Rights Reserved.
-
- This file is part of GtkRadiant.
-
- GtkRadiant is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- GtkRadiant is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GtkRadiant; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#if !defined ( INCLUDED_XORRECTANGLE_H )
-#define INCLUDED_XORRECTANGLE_H
-
-#include <cairo.h>
-#include <uilib/uilib.h>
-#include "math/vector.h"
-
-class rectangle_t
-{
-public:
-rectangle_t()
- : x( 0 ), y( 0 ), w( 0 ), h( 0 )
-{}
-rectangle_t( float _x, float _y, float _w, float _h )
- : x( _x ), y( _y ), w( _w ), h( _h )
-{}
-float x;
-float y;
-float w;
-float h;
-};
-
-struct Coord2D
-{
- float x, y;
- Coord2D( float _x, float _y )
- : x( _x ), y( _y ){
- }
-};
-
-inline Coord2D coord2d_device2screen( const Coord2D& coord, unsigned int width, unsigned int height ){
- return Coord2D( ( ( coord.x + 1.0f ) * 0.5f ) * width, ( ( coord.y + 1.0f ) * 0.5f ) * height );
-}
-
-inline rectangle_t rectangle_from_area( const float min[2], const float max[2], unsigned int width, unsigned int height ){
- Coord2D botleft( coord2d_device2screen( Coord2D( min[0], min[1] ), width, height ) );
- Coord2D topright( coord2d_device2screen( Coord2D( max[0], max[1] ), width, height ) );
- return rectangle_t( botleft.x, botleft.y, topright.x - botleft.x, topright.y - botleft.y );
-}
-
-class XORRectangle
-{
-
-rectangle_t m_rectangle;
-
-ui::GLArea m_widget;
-cairo_t *cr;
-
-bool initialised() const;
-void lazy_init();
-void draw() const;
-
-public:
-<<<<<<< HEAD
-XORRectangle( ui::GLArea widget );
-~XORRectangle();
-void set( rectangle_t rectangle );
-=======
-XORRectangle( GtkWidget* widget ) : m_widget( widget ){
-}
-~XORRectangle(){
-}
-void set( rectangle_t rectangle ){
- if ( GTK_WIDGET_REALIZED( m_widget ) ) {
- if( m_rectangle.w != rectangle.w || m_rectangle.h != rectangle.h ){
- //if( !(m_rectangle.w == 0 && m_rectangle.h == 0 && rectangle.w == 0 && rectangle.h == 0) ){
- //globalOutputStream() << "m_x" << m_rectangle.x << " m_y" << m_rectangle.y << " m_w" << m_rectangle.w << " m_h" << m_rectangle.h << "\n";
- //globalOutputStream() << "__x" << rectangle.x << " __y" << rectangle.y << " __w" << rectangle.w << " __h" << rectangle.h << "\n";
- if ( glwidget_make_current( m_widget ) != FALSE ) {
- GlobalOpenGL_debugAssertNoErrors();
-
- gint width, height;
- gdk_gl_drawable_get_size( gtk_widget_get_gl_drawable( m_widget ), &width, &height );
-
- glViewport( 0, 0, width, height );
- glMatrixMode( GL_PROJECTION );
- glLoadIdentity();
- glOrtho( 0, width, 0, height, -100, 100 );
-
- glMatrixMode( GL_MODELVIEW );
- glLoadIdentity();
-
- glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
- glDisable( GL_DEPTH_TEST );
-
- glDrawBuffer( GL_FRONT );
-
- glEnable( GL_BLEND );
- glBlendFunc( GL_ONE_MINUS_DST_COLOR, GL_ZERO );
-
- glLineWidth( 2 );
- glColor3f( 1, 1, 1 );
- glDisable( GL_TEXTURE_2D );
- glBegin( GL_LINE_LOOP );
- glVertex2f( m_rectangle.x, m_rectangle.y + m_rectangle.h );
- glVertex2f( m_rectangle.x + m_rectangle.w, m_rectangle.y + m_rectangle.h );
- glVertex2f( m_rectangle.x + m_rectangle.w, m_rectangle.y );
- glVertex2f( m_rectangle.x, m_rectangle.y );
- glEnd();
-
- glBegin( GL_LINE_LOOP );
- glVertex2f( rectangle.x, rectangle.y + rectangle.h );
- glVertex2f( rectangle.x + rectangle.w, rectangle.y + rectangle.h );
- glVertex2f( rectangle.x + rectangle.w, rectangle.y );
- glVertex2f( rectangle.x, rectangle.y );
- glEnd();
-
- glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
- glDrawBuffer( GL_BACK );
- GlobalOpenGL_debugAssertNoErrors();
- //glwidget_swap_buffers( m_widget );
- glwidget_make_current( m_widget );
- }
- }
- m_rectangle = rectangle;
- }
-}
->>>>>>> 3a78d902017a780e65f21f12c709aa746dfcab84
-};
-
-
-#endif
+++ /dev/null
-/*
- Copyright (C) 1999-2006 Id Software, Inc. and contributors.
- For a list of contributors, see the accompanying CONTRIBUTORS file.
-
- This file is part of GtkRadiant.
-
- GtkRadiant is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- GtkRadiant is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GtkRadiant; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "brushmanip.h"
-
-
-#include "gtkutil/widget.h"
-#include "gtkutil/menu.h"
-#include "gtkmisc.h"
-#include "brushnode.h"
-#include "map.h"
-#include "texwindow.h"
-#include "gtkdlgs.h"
-#include "commands.h"
-#include "mainframe.h"
-#include "dialog.h"
-#include "xywindow.h"
-#include "preferences.h"
-
-#include <list>
-#include <gdk/gdkkeysyms.h>
-
-void Brush_ConstructCuboid( Brush& brush, const AABB& bounds, const char* shader, const TextureProjection& projection ){
- const unsigned char box[3][2] = { { 0, 1 }, { 2, 0 }, { 1, 2 } };
- Vector3 mins( vector3_subtracted( bounds.origin, bounds.extents ) );
- Vector3 maxs( vector3_added( bounds.origin, bounds.extents ) );
-
- brush.clear();
- brush.reserve( 6 );
-
- {
- for ( int i = 0; i < 3; ++i )
- {
- Vector3 planepts1( maxs );
- Vector3 planepts2( maxs );
- planepts2[box[i][0]] = mins[box[i][0]];
- planepts1[box[i][1]] = mins[box[i][1]];
-
- brush.addPlane( maxs, planepts1, planepts2, shader, projection );
- }
- }
- {
- for ( int i = 0; i < 3; ++i )
- {
- Vector3 planepts1( mins );
- Vector3 planepts2( mins );
- planepts1[box[i][0]] = maxs[box[i][0]];
- planepts2[box[i][1]] = maxs[box[i][1]];
-
- brush.addPlane( mins, planepts1, planepts2, shader, projection );
- }
- }
-}
-
-inline float max_extent( const Vector3& extents ){
- return std::max( std::max( extents[0], extents[1] ), extents[2] );
-}
-
-inline float max_extent_2d( const Vector3& extents, int axis ){
- switch ( axis )
- {
- case 0:
- return std::max( extents[1], extents[2] );
- case 1:
- return std::max( extents[0], extents[2] );
- default:
- return std::max( extents[0], extents[1] );
- }
-}
-
-const std::size_t c_brushPrism_minSides = 3;
-const std::size_t c_brushPrism_maxSides = c_brush_maxFaces - 2;
-const char* const c_brushPrism_name = "brushPrism";
-
-void Brush_ConstructPrism( Brush& brush, const AABB& bounds, std::size_t sides, int axis, const char* shader, const TextureProjection& projection ){
- if ( sides < c_brushPrism_minSides ) {
- globalErrorStream() << c_brushPrism_name << ": sides " << Unsigned( sides ) << ": too few sides, minimum is " << Unsigned( c_brushPrism_minSides ) << "\n";
- return;
- }
- if ( sides > c_brushPrism_maxSides ) {
- globalErrorStream() << c_brushPrism_name << ": sides " << Unsigned( sides ) << ": too many sides, maximum is " << Unsigned( c_brushPrism_maxSides ) << "\n";
- return;
- }
-
- brush.clear();
- brush.reserve( sides + 2 );
-
- Vector3 mins( vector3_subtracted( bounds.origin, bounds.extents ) );
- Vector3 maxs( vector3_added( bounds.origin, bounds.extents ) );
-
- float radius = max_extent_2d( bounds.extents, axis );
- const Vector3& mid = bounds.origin;
- Vector3 planepts[3];
-
- planepts[2][( axis + 1 ) % 3] = mins[( axis + 1 ) % 3];
- planepts[2][( axis + 2 ) % 3] = mins[( axis + 2 ) % 3];
- planepts[2][axis] = maxs[axis];
- planepts[1][( axis + 1 ) % 3] = maxs[( axis + 1 ) % 3];
- planepts[1][( axis + 2 ) % 3] = mins[( axis + 2 ) % 3];
- planepts[1][axis] = maxs[axis];
- planepts[0][( axis + 1 ) % 3] = maxs[( axis + 1 ) % 3];
- planepts[0][( axis + 2 ) % 3] = maxs[( axis + 2 ) % 3];
- planepts[0][axis] = maxs[axis];
-
- brush.addPlane( planepts[0], planepts[1], planepts[2], shader, projection );
-
- planepts[0][( axis + 1 ) % 3] = mins[( axis + 1 ) % 3];
- planepts[0][( axis + 2 ) % 3] = mins[( axis + 2 ) % 3];
- planepts[0][axis] = mins[axis];
- planepts[1][( axis + 1 ) % 3] = maxs[( axis + 1 ) % 3];
- planepts[1][( axis + 2 ) % 3] = mins[( axis + 2 ) % 3];
- planepts[1][axis] = mins[axis];
- planepts[2][( axis + 1 ) % 3] = maxs[( axis + 1 ) % 3];
- planepts[2][( axis + 2 ) % 3] = maxs[( axis + 2 ) % 3];
- planepts[2][axis] = mins[axis];
-
- brush.addPlane( planepts[0], planepts[1], planepts[2], shader, projection );
-
- for ( std::size_t i = 0 ; i < sides ; ++i )
- {
- double sv = sin( i * 3.14159265 * 2 / sides );
- double cv = cos( i * 3.14159265 * 2 / sides );
-
-// planepts[0][( axis + 1 ) % 3] = static_cast<float>( floor( mid[( axis + 1 ) % 3] + radius * cv + 0.5 ) );
-// planepts[0][( axis + 2 ) % 3] = static_cast<float>( floor( mid[( axis + 2 ) % 3] + radius * sv + 0.5 ) );
- planepts[0][( axis + 1 ) % 3] = static_cast<float>( mid[( axis + 1 ) % 3] + radius * cv );
- planepts[0][( axis + 2 ) % 3] = static_cast<float>( mid[( axis + 2 ) % 3] + radius * sv );
- planepts[0][axis] = mins[axis];
-
- planepts[1][( axis + 1 ) % 3] = planepts[0][( axis + 1 ) % 3];
- planepts[1][( axis + 2 ) % 3] = planepts[0][( axis + 2 ) % 3];
- planepts[1][axis] = maxs[axis];
-
-// planepts[2][( axis + 1 ) % 3] = static_cast<float>( floor( planepts[0][( axis + 1 ) % 3] - radius * sv + 0.5 ) );
-// planepts[2][( axis + 2 ) % 3] = static_cast<float>( floor( planepts[0][( axis + 2 ) % 3] + radius * cv + 0.5 ) );
- planepts[2][( axis + 1 ) % 3] = static_cast<float>( planepts[0][( axis + 1 ) % 3] - radius * sv );
- planepts[2][( axis + 2 ) % 3] = static_cast<float>( planepts[0][( axis + 2 ) % 3] + radius * cv );
- planepts[2][axis] = maxs[axis];
- //globalOutputStream() << planepts[0] << " " << planepts[2] << " #" << i << " sin " << sv << " cos " << cv << "\n";
-
- brush.addPlane( planepts[0], planepts[1], planepts[2], shader, projection );
- }
-}
-
-const std::size_t c_brushCone_minSides = 3;
-const std::size_t c_brushCone_maxSides = c_brush_maxFaces - 1;
-const char* const c_brushCone_name = "brushCone";
-
-void Brush_ConstructCone( Brush& brush, const AABB& bounds, std::size_t sides, const char* shader, const TextureProjection& projection ){
- if ( sides < c_brushCone_minSides ) {
- globalErrorStream() << c_brushCone_name << ": sides " << Unsigned( sides ) << ": too few sides, minimum is " << Unsigned( c_brushCone_minSides ) << "\n";
- return;
- }
- if ( sides > c_brushCone_maxSides ) {
- globalErrorStream() << c_brushCone_name << ": sides " << Unsigned( sides ) << ": too many sides, maximum is " << Unsigned( c_brushCone_maxSides ) << "\n";
- return;
- }
-
- brush.clear();
- brush.reserve( sides + 1 );
-
- Vector3 mins( vector3_subtracted( bounds.origin, bounds.extents ) );
- Vector3 maxs( vector3_added( bounds.origin, bounds.extents ) );
-
- float radius = max_extent( bounds.extents );
- const Vector3& mid = bounds.origin;
- Vector3 planepts[3];
-
- planepts[0][0] = mins[0]; planepts[0][1] = mins[1]; planepts[0][2] = mins[2];
- planepts[1][0] = maxs[0]; planepts[1][1] = mins[1]; planepts[1][2] = mins[2];
- planepts[2][0] = maxs[0]; planepts[2][1] = maxs[1]; planepts[2][2] = mins[2];
-
- brush.addPlane( planepts[0], planepts[1], planepts[2], shader, projection );
-
- for ( std::size_t i = 0 ; i < sides ; ++i )
- {
- double sv = sin( i * 3.14159265 * 2 / sides );
- double cv = cos( i * 3.14159265 * 2 / sides );
-
- planepts[0][0] = static_cast<float>( mid[0] + radius * cv );
- planepts[0][1] = static_cast<float>( mid[1] + radius * sv );
-// planepts[0][0] = static_cast<float>( floor( mid[0] + radius * cv + 0.5 ) );
-// planepts[0][1] = static_cast<float>( floor( mid[1] + radius * sv + 0.5 ) );
- planepts[0][2] = mins[2];
-
- planepts[1][0] = mid[0];
- planepts[1][1] = mid[1];
- planepts[1][2] = maxs[2];
-
- planepts[2][0] = static_cast<float>( planepts[0][0] - radius * sv );
- planepts[2][1] = static_cast<float>( planepts[0][1] + radius * cv );
-// planepts[2][0] = static_cast<float>( floor( planepts[0][0] - radius * sv + 0.5 ) );
-// planepts[2][1] = static_cast<float>( floor( planepts[0][1] + radius * cv + 0.5 ) );
- planepts[2][2] = maxs[2];
-
- brush.addPlane( planepts[0], planepts[1], planepts[2], shader, projection );
- }
-}
-
-const std::size_t c_brushSphere_minSides = 3;
-const std::size_t c_brushSphere_maxSides = 31;
-const char* const c_brushSphere_name = "brushSphere";
-
-void Brush_ConstructSphere( Brush& brush, const AABB& bounds, std::size_t sides, const char* shader, const TextureProjection& projection ){
- if ( sides < c_brushSphere_minSides ) {
- globalErrorStream() << c_brushSphere_name << ": sides " << Unsigned( sides ) << ": too few sides, minimum is " << Unsigned( c_brushSphere_minSides ) << "\n";
- return;
- }
- if ( sides > c_brushSphere_maxSides ) {
- globalErrorStream() << c_brushSphere_name << ": sides " << Unsigned( sides ) << ": too many sides, maximum is " << Unsigned( c_brushSphere_maxSides ) << "\n";
- return;
- }
-
- brush.clear();
- brush.reserve( sides * sides );
-
- float radius = max_extent( bounds.extents );
- const Vector3& mid = bounds.origin;
- Vector3 planepts[3];
-
- double dt = 2 * c_pi / sides;
- double dp = c_pi / sides;
- for ( std::size_t i = 0; i < sides; i++ )
- {
- for ( std::size_t j = 0; j < sides - 1; j++ )
- {
- double t = i * dt;
- double p = float(j * dp - c_pi / 2);
-
- planepts[0] = vector3_added( mid, vector3_scaled( vector3_for_spherical( t, p ), radius ) );
- planepts[1] = vector3_added( mid, vector3_scaled( vector3_for_spherical( t, p + dp ), radius ) );
- planepts[2] = vector3_added( mid, vector3_scaled( vector3_for_spherical( t + dt, p + dp ), radius ) );
-
- brush.addPlane( planepts[0], planepts[1], planepts[2], shader, projection );
- }
- }
-
- {
- double p = ( sides - 1 ) * dp - c_pi / 2;
- for ( std::size_t i = 0; i < sides; i++ )
- {
- double t = i * dt;
-
- planepts[0] = vector3_added( mid, vector3_scaled( vector3_for_spherical( t, p ), radius ) );
- planepts[1] = vector3_added( mid, vector3_scaled( vector3_for_spherical( t + dt, p + dp ), radius ) );
- planepts[2] = vector3_added( mid, vector3_scaled( vector3_for_spherical( t + dt, p ), radius ) );
-
- brush.addPlane( planepts[0], planepts[1], planepts[2], shader, projection );
- }
- }
-}
-
-const std::size_t c_brushRock_minSides = 10;
-const std::size_t c_brushRock_maxSides = 1000;
-const char* const c_brushRock_name = "brushRock";
-
-void Brush_ConstructRock( Brush& brush, const AABB& bounds, std::size_t sides, const char* shader, const TextureProjection& projection ){
- if ( sides < c_brushRock_minSides ) {
- globalErrorStream() << c_brushRock_name << ": sides " << Unsigned( sides ) << ": too few sides, minimum is " << Unsigned( c_brushRock_minSides ) << "\n";
- return;
- }
- if ( sides > c_brushRock_maxSides ) {
- globalErrorStream() << c_brushRock_name << ": sides " << Unsigned( sides ) << ": too many sides, maximum is " << Unsigned( c_brushRock_maxSides ) << "\n";
- return;
- }
-
- brush.clear();
- brush.reserve( sides * sides );
-
- float radius = max_extent( bounds.extents );
- const Vector3& mid = bounds.origin;
- Vector3 planepts[3];
-
- for ( std::size_t j = 0; j < sides; j++ )
- {
- planepts[0][0] = rand() - ( RAND_MAX / 2 );
- planepts[0][1] = rand() - ( RAND_MAX / 2 );
- planepts[0][2] = rand() - ( RAND_MAX / 2 );
- vector3_normalise( planepts[0] );
-
- // find two vectors that are perpendicular to planepts[0]
- ComputeAxisBase( planepts[0], planepts[1], planepts[2] );
-
- planepts[0] = vector3_added( mid, vector3_scaled( planepts[0], radius ) );
- planepts[1] = vector3_added( planepts[0], vector3_scaled( planepts[1], radius ) );
- planepts[2] = vector3_added( planepts[0], vector3_scaled( planepts[2], radius ) );
-
-#if 0
- // make sure the orientation is right
- if ( vector3_dot( vector3_subtracted( planepts[0], mid ), vector3_cross( vector3_subtracted( planepts[1], mid ), vector3_subtracted( planepts[2], mid ) ) ) > 0 ) {
- Vector3 h;
- h = planepts[1];
- planepts[1] = planepts[2];
- planepts[2] = h;
- globalOutputStream() << "flip\n";
- }
- else{
- globalOutputStream() << "no flip\n";
- }
-#endif
-
- brush.addPlane( planepts[0], planepts[1], planepts[2], shader, projection );
- }
-}
-
-int GetViewAxis(){
- switch ( GlobalXYWnd_getCurrentViewType() )
- {
- case XY:
- return 2;
- case XZ:
- return 1;
- case YZ:
- return 0;
- }
- return 2;
-}
-
-void Brush_ConstructPrefab( Brush& brush, EBrushPrefab type, const AABB& bounds, std::size_t sides, const char* shader, const TextureProjection& projection ){
- switch ( type )
- {
- case eBrushCuboid:
- {
- UndoableCommand undo( "brushCuboid" );
-
- Brush_ConstructCuboid( brush, bounds, shader, projection );
- }
- break;
- case eBrushPrism:
- {
- int axis = GetViewAxis();
- StringOutputStream command;
- command << c_brushPrism_name << " -sides " << Unsigned( sides ) << " -axis " << axis;
- UndoableCommand undo( command.c_str() );
-
- Brush_ConstructPrism( brush, bounds, sides, axis, shader, projection );
- }
- break;
- case eBrushCone:
- {
- StringOutputStream command;
- command << c_brushCone_name << " -sides " << Unsigned( sides );
- UndoableCommand undo( command.c_str() );
-
- Brush_ConstructCone( brush, bounds, sides, shader, projection );
- }
- break;
- case eBrushSphere:
- {
- StringOutputStream command;
- command << c_brushSphere_name << " -sides " << Unsigned( sides );
- UndoableCommand undo( command.c_str() );
-
- Brush_ConstructSphere( brush, bounds, sides, shader, projection );
- }
- break;
- case eBrushRock:
- {
- StringOutputStream command;
- command << c_brushRock_name << " -sides " << Unsigned( sides );
- UndoableCommand undo( command.c_str() );
-
- Brush_ConstructRock( brush, bounds, sides, shader, projection );
- }
- break;
- }
-}
-
-
-void ConstructRegionBrushes( scene::Node* brushes[6], const Vector3& region_mins, const Vector3& region_maxs ){
- {
- // set mins
- Vector3 mins( region_mins[0] - 32, region_mins[1] - 32, region_mins[2] - 32 );
-
- // vary maxs
- for ( std::size_t i = 0; i < 3; i++ )
- {
- Vector3 maxs( region_maxs[0] + 32, region_maxs[1] + 32, region_maxs[2] + 32 );
- maxs[i] = region_mins[i];
- Brush_ConstructCuboid( *Node_getBrush( *brushes[i] ), aabb_for_minmax( mins, maxs ), texdef_name_default(), TextureProjection() );
- }
- }
-
- {
- // set maxs
- Vector3 maxs( region_maxs[0] + 32, region_maxs[1] + 32, region_maxs[2] + 32 );
-
- // vary mins
- for ( std::size_t i = 0; i < 3; i++ )
- {
- Vector3 mins( region_mins[0] - 32, region_mins[1] - 32, region_mins[2] - 32 );
- mins[i] = region_maxs[i];
- Brush_ConstructCuboid( *Node_getBrush( *brushes[i + 3] ), aabb_for_minmax( mins, maxs ), texdef_name_default(), TextureProjection() );
- }
- }
-}
-
-
-void Scene_BrushSetTexdef_Selected( scene::Graph& graph, const TextureProjection& projection ){
- Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) {
- face.SetTexdef(projection);
- });
- SceneChangeNotify();
-}
-
-void Scene_BrushSetTexdef_Component_Selected( scene::Graph& graph, const TextureProjection& projection ){
- Scene_ForEachSelectedBrushFace(graph, [&](Face &face) {
- face.SetTexdef(projection);
- });
- SceneChangeNotify();
-}
-
-
-<<<<<<< HEAD
-=======
-class FaceSetFlags
-{
-const ContentsFlagsValue& m_flags;
-public:
-FaceSetFlags( const ContentsFlagsValue& flags ) : m_flags( flags ){
-}
-void operator()( Face& face ) const {
- face.SetFlags( m_flags );
-}
-};
-
->>>>>>> 3a78d902017a780e65f21f12c709aa746dfcab84
-void Scene_BrushSetFlags_Selected( scene::Graph& graph, const ContentsFlagsValue& flags ){
- Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) {
- face.SetFlags(flags);
- });
- SceneChangeNotify();
-}
-
-void Scene_BrushSetFlags_Component_Selected( scene::Graph& graph, const ContentsFlagsValue& flags ){
- Scene_ForEachSelectedBrushFace(graph, [&](Face &face) {
- face.SetFlags(flags);
- });
- SceneChangeNotify();
-}
-
-void Scene_BrushShiftTexdef_Selected( scene::Graph& graph, float s, float t ){
- Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) {
- face.ShiftTexdef(s, t);
- });
- SceneChangeNotify();
-}
-
-void Scene_BrushShiftTexdef_Component_Selected( scene::Graph& graph, float s, float t ){
- Scene_ForEachSelectedBrushFace(graph, [&](Face &face) {
- face.ShiftTexdef(s, t);
- });
- SceneChangeNotify();
-}
-
-void Scene_BrushScaleTexdef_Selected( scene::Graph& graph, float s, float t ){
- Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) {
- face.ScaleTexdef(s, t);
- });
- SceneChangeNotify();
-}
-
-void Scene_BrushScaleTexdef_Component_Selected( scene::Graph& graph, float s, float t ){
- Scene_ForEachSelectedBrushFace(graph, [&](Face &face) {
- face.ScaleTexdef(s, t);
- });
- SceneChangeNotify();
-}
-
-void Scene_BrushRotateTexdef_Selected( scene::Graph& graph, float angle ){
- Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) {
- face.RotateTexdef(angle);
- });
- SceneChangeNotify();
-}
-
-void Scene_BrushRotateTexdef_Component_Selected( scene::Graph& graph, float angle ){
- Scene_ForEachSelectedBrushFace(graph, [&](Face &face) {
- face.RotateTexdef(angle);
- });
- SceneChangeNotify();
-}
-
-
-void Scene_BrushSetShader_Selected( scene::Graph& graph, const char* name ){
- Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) {
- face.SetShader(name);
- });
- SceneChangeNotify();
-}
-
-void Scene_BrushSetShader_Component_Selected( scene::Graph& graph, const char* name ){
- Scene_ForEachSelectedBrushFace(graph, [&](Face &face) {
- face.SetShader(name);
- });
- SceneChangeNotify();
-}
-
-void Scene_BrushSetDetail_Selected( scene::Graph& graph, bool detail ){
- Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) {
- face.setDetail(detail);
- });
- SceneChangeNotify();
-}
-
-bool Face_FindReplaceShader( Face& face, const char* find, const char* replace ){
- if ( shader_equal( face.GetShader(), find ) ) {
- face.SetShader( replace );
- return true;
- }
- return false;
-}
-
-bool DoingSearch( const char *repl ){
- return ( repl == NULL || ( strcmp( "textures/", repl ) == 0 ) );
-}
-
-void Scene_BrushFindReplaceShader( scene::Graph& graph, const char* find, const char* replace ){
- if ( DoingSearch( replace ) ) {
- Scene_ForEachBrush_ForEachFaceInstance(graph, [&](FaceInstance &faceinst) {
- if (shader_equal(faceinst.getFace().GetShader(), find)) {
- faceinst.setSelected(SelectionSystem::eFace, true);
- }
- });
- }
- else
- {
- Scene_ForEachBrush_ForEachFace(graph, [&](Face &face) { Face_FindReplaceShader(face, find, replace); });
- }
-}
-
-void Scene_BrushFindReplaceShader_Selected( scene::Graph& graph, const char* find, const char* replace ){
- if ( DoingSearch( replace ) ) {
- Scene_ForEachSelectedBrush_ForEachFaceInstance(graph, [&](FaceInstance &faceinst) {
- if (shader_equal(faceinst.getFace().GetShader(), find)) {
- faceinst.setSelected(SelectionSystem::eFace, true);
- }
- });
- }
- else
- {
- Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) {
- Face_FindReplaceShader(face, find, replace);
- });
- }
-}
-
-// TODO: find for components
-// d1223m: dont even know what they are...
-void Scene_BrushFindReplaceShader_Component_Selected( scene::Graph& graph, const char* find, const char* replace ){
- if ( DoingSearch( replace ) ) {
-
- }
- else
- {
- Scene_ForEachSelectedBrushFace(graph, [&](Face &face) {
- Face_FindReplaceShader(face, find, replace);
- });
- }
-}
-
-
-void Scene_BrushFitTexture_Selected( scene::Graph& graph, float s_repeat, float t_repeat ){
- Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) {
- face.FitTexture(s_repeat, t_repeat);
- });
- SceneChangeNotify();
-}
-
-void Scene_BrushFitTexture_Component_Selected( scene::Graph& graph, float s_repeat, float t_repeat ){
- Scene_ForEachSelectedBrushFace(graph, [&](Face &face) {
- face.FitTexture(s_repeat, t_repeat);
- });
- SceneChangeNotify();
-}
-
-TextureProjection g_defaultTextureProjection;
-
-const TextureProjection& TextureTransform_getDefault(){
- TexDef_Construct_Default( g_defaultTextureProjection );
- return g_defaultTextureProjection;
-}
-
-void Scene_BrushConstructPrefab( scene::Graph& graph, EBrushPrefab type, std::size_t sides, const char* shader ){
- if ( GlobalSelectionSystem().countSelected() != 0 ) {
- const scene::Path& path = GlobalSelectionSystem().ultimateSelected().path();
-
- Brush* brush = Node_getBrush( path.top() );
- if ( brush != 0 ) {
- AABB bounds = brush->localAABB(); // copy bounds because the brush will be modified
- Brush_ConstructPrefab( *brush, type, bounds, sides, shader, TextureTransform_getDefault() );
- SceneChangeNotify();
- }
- }
-}
-
-void Scene_BrushResize_Selected( scene::Graph& graph, const AABB& bounds, const char* shader ){
- if ( GlobalSelectionSystem().countSelected() != 0 ) {
- const scene::Path& path = GlobalSelectionSystem().ultimateSelected().path();
-
- Brush* brush = Node_getBrush( path.top() );
- if ( brush != 0 ) {
- Brush_ConstructCuboid( *brush, bounds, shader, TextureTransform_getDefault() );
- SceneChangeNotify();
- }
- }
-}
-
-bool Brush_hasShader( const Brush& brush, const char* name ){
- for ( Brush::const_iterator i = brush.begin(); i != brush.end(); ++i )
- {
- if ( shader_equal( ( *i )->GetShader(), name ) ) {
- return true;
- }
- }
- return false;
-}
-
-class BrushSelectByShaderWalker : public scene::Graph::Walker
-{
-const char* m_name;
-public:
-BrushSelectByShaderWalker( const char* name )
- : m_name( name ){
-}
-
-bool pre( const scene::Path& path, scene::Instance& instance ) const {
- if ( path.top().get().visible() ) {
- Brush* brush = Node_getBrush( path.top() );
- if ( brush != 0 && Brush_hasShader( *brush, m_name ) ) {
- Instance_getSelectable( instance )->setSelected( true );
- }
- }
- else{
- return false;
- }
- return true;
-}
-};
-
-void Scene_BrushSelectByShader( scene::Graph& graph, const char* name ){
- graph.traverse( BrushSelectByShaderWalker( name ) );
-}
-
-void Scene_BrushSelectByShader_Component( scene::Graph& graph, const char* name ){
- Scene_ForEachSelectedBrush_ForEachFaceInstance(graph, [&](FaceInstance &face) {
- printf("checking %s = %s\n", face.getFace().GetShader(), name);
- if (shader_equal(face.getFace().GetShader(), name)) {
- face.setSelected( SelectionSystem::eFace, true );
- }
- });
-}
-
-void Scene_BrushGetTexdef_Selected( scene::Graph& graph, TextureProjection& projection ){
- bool done = false;
- Scene_ForEachSelectedBrush_ForEachFace(graph, [&](Face &face) {
- if (!done) {
- done = true;
- face.GetTexdef(projection);
-}
- });
-}
-
-void Scene_BrushGetTexdef_Component_Selected( scene::Graph& graph, TextureProjection& projection ){
-#if 1
- if ( !g_SelectedFaceInstances.empty() ) {
- FaceInstance& faceInstance = g_SelectedFaceInstances.last();
- faceInstance.getFace().GetTexdef( projection );
- }
-#else
- FaceGetTexdef visitor( projection );
- Scene_ForEachSelectedBrushFace( graph, visitor );
-#endif
-}
-
-void Scene_BrushGetShaderSize_Component_Selected( scene::Graph& graph, size_t& width, size_t& height ){
- if ( !g_SelectedFaceInstances.empty() ) {
- FaceInstance& faceInstance = g_SelectedFaceInstances.last();
- width = faceInstance.getFace().getShader().width();
- height = faceInstance.getFace().getShader().height();
- }
-}
-
-
-void Scene_BrushGetFlags_Selected( scene::Graph& graph, ContentsFlagsValue& flags ){
-#if 1
- if ( GlobalSelectionSystem().countSelected() != 0 ) {
- BrushInstance* brush = Instance_getBrush( GlobalSelectionSystem().ultimateSelected() );
- if ( brush != 0 ) {
- bool done = false;
- Brush_forEachFace(*brush, [&](Face &face) {
- if (!done) {
- done = true;
- face.GetFlags(flags);
- }
- });
- }
- }
-#else
- Scene_ForEachSelectedBrush_ForEachFace( graph, FaceGetFlags( flags ) );
-#endif
-}
-
-void Scene_BrushGetFlags_Component_Selected( scene::Graph& graph, ContentsFlagsValue& flags ){
-#if 1
- if ( !g_SelectedFaceInstances.empty() ) {
- FaceInstance& faceInstance = g_SelectedFaceInstances.last();
- faceInstance.getFace().GetFlags( flags );
- }
-#else
- Scene_ForEachSelectedBrushFace( graph, FaceGetFlags( flags ) );
-#endif
-}
-
-
-void Scene_BrushGetShader_Selected( scene::Graph& graph, CopiedString& shader ){
-#if 1
- if ( GlobalSelectionSystem().countSelected() != 0 ) {
- BrushInstance* brush = Instance_getBrush( GlobalSelectionSystem().ultimateSelected() );
- if ( brush != 0 ) {
- bool done = false;
- Brush_forEachFace(*brush, [&](Face &face) {
- if (!done) {
- done = true;
- shader = face.GetShader();
- }
- });
- }
- }
-#else
- Scene_ForEachSelectedBrush_ForEachFace( graph, FaceGetShader( shader ) );
-#endif
-}
-
-void Scene_BrushGetShader_Component_Selected( scene::Graph& graph, CopiedString& shader ){
-#if 1
- if ( !g_SelectedFaceInstances.empty() ) {
- FaceInstance& faceInstance = g_SelectedFaceInstances.last();
- shader = faceInstance.getFace().GetShader();
- }
-#else
- FaceGetShader visitor( shader );
- Scene_ForEachSelectedBrushFace( graph, visitor );
-#endif
-}
-
-
-class filter_face_shader : public FaceFilter
-{
-const char* m_shader;
-public:
-filter_face_shader( const char* shader ) : m_shader( shader ){
-}
-
-bool filter( const Face& face ) const {
- return shader_equal( face.GetShader(), m_shader );
-}
-};
-
-class filter_face_shader_prefix : public FaceFilter
-{
-const char* m_prefix;
-public:
-filter_face_shader_prefix( const char* prefix ) : m_prefix( prefix ){
-}
-
-bool filter( const Face& face ) const {
- return shader_equal_n( face.GetShader(), m_prefix, strlen( m_prefix ) );
-}
-};
-
-class filter_face_flags : public FaceFilter
-{
-int m_flags;
-public:
-filter_face_flags( int flags ) : m_flags( flags ){
-}
-
-bool filter( const Face& face ) const {
- return ( face.getShader().shaderFlags() & m_flags ) != 0;
-}
-};
-
-class filter_face_contents : public FaceFilter
-{
-int m_contents;
-public:
-filter_face_contents( int contents ) : m_contents( contents ){
-}
-
-bool filter( const Face& face ) const {
- return ( face.getShader().m_flags.m_contentFlags & m_contents ) != 0;
-}
-};
-
-
-
-class filter_brush_any_face : public BrushFilter
-{
-FaceFilter* m_filter;
-public:
-filter_brush_any_face( FaceFilter* filter ) : m_filter( filter ){
-}
-
-bool filter( const Brush& brush ) const {
- bool filtered = false;
- Brush_forEachFace(brush, [&](Face &face) {
- if (m_filter->filter(face)) {
- filtered = true;
- }
- });
- return filtered;
-}
-};
-
-class filter_brush_all_faces : public BrushFilter
-{
-FaceFilter* m_filter;
-public:
-filter_brush_all_faces( FaceFilter* filter ) : m_filter( filter ){
-}
-bool filter( const Brush& brush ) const {
- bool filtered = true;
- Brush_forEachFace(brush, [&](Face &face) {
- if (!m_filter->filter(face)) {
- filtered = false;
- }
- });
- return filtered;
-}
-};
-
-
-filter_face_flags g_filter_face_clip( QER_CLIP );
-filter_brush_all_faces g_filter_brush_clip( &g_filter_face_clip );
-
-filter_face_shader g_filter_face_clip_q2( "textures/clip" );
-filter_brush_all_faces g_filter_brush_clip_q2( &g_filter_face_clip_q2 );
-
-filter_face_shader g_filter_face_weapclip( "textures/common/weapclip" );
-filter_brush_all_faces g_filter_brush_weapclip( &g_filter_face_weapclip );
-
-filter_face_shader g_filter_face_commonclip( "textures/common/clip" );
-filter_brush_all_faces g_filter_brush_commonclip( &g_filter_face_commonclip );
-
-filter_face_shader g_filter_face_fullclip( "textures/common/fullclip" );
-filter_brush_all_faces g_filter_brush_fullclip( &g_filter_face_fullclip );
-
-filter_face_shader g_filter_face_botclip( "textures/common/botclip" );
-filter_brush_all_faces g_filter_brush_botclip( &g_filter_face_botclip );
-
-filter_face_shader_prefix g_filter_face_caulk( "textures/common/caulk" );
-filter_brush_all_faces g_filter_brush_caulk( &g_filter_face_caulk );
-
-filter_face_shader_prefix g_filter_face_caulk_ja( "textures/system/caulk" );
-filter_brush_all_faces g_filter_brush_caulk_ja( &g_filter_face_caulk_ja );
-
-filter_face_flags g_filter_face_liquids( QER_LIQUID );
-filter_brush_any_face g_filter_brush_liquids( &g_filter_face_liquids );
-
-filter_face_shader_prefix g_filter_face_liquidsdir( "textures/liquids/" );
-filter_brush_any_face g_filter_brush_liquidsdir( &g_filter_face_liquidsdir );
-
-filter_face_shader g_filter_face_hint( "textures/common/hint" );
-filter_brush_any_face g_filter_brush_hint( &g_filter_face_hint );
-
-filter_face_shader g_filter_face_hintlocal( "textures/common/hintlocal" );
-filter_brush_any_face g_filter_brush_hintlocal( &g_filter_face_hintlocal );
-
-filter_face_shader g_filter_face_hint_q2( "textures/hint" );
-filter_brush_any_face g_filter_brush_hint_q2( &g_filter_face_hint_q2 );
-
-filter_face_shader g_filter_face_hint_ja( "textures/system/hint" );
-filter_brush_any_face g_filter_brush_hint_ja( &g_filter_face_hint_ja );
-
-filter_face_shader g_filter_face_areaportal( "textures/common/areaportal" );
-filter_brush_any_face g_filter_brush_areaportal( &g_filter_face_areaportal );
-
-filter_face_shader g_filter_face_visportal( "textures/editor/visportal" );
-filter_brush_any_face g_filter_brush_visportal( &g_filter_face_visportal );
-
-filter_face_shader g_filter_face_clusterportal( "textures/common/clusterportal" );
-filter_brush_all_faces g_filter_brush_clusterportal( &g_filter_face_clusterportal );
-
-filter_face_shader g_filter_face_lightgrid( "textures/common/lightgrid" );
-filter_brush_all_faces g_filter_brush_lightgrid( &g_filter_face_lightgrid );
-
-filter_face_flags g_filter_face_translucent( QER_TRANS | QER_ALPHATEST );
-filter_brush_any_face g_filter_brush_translucent( &g_filter_face_translucent );
-
-filter_face_contents g_filter_face_detail( BRUSH_DETAIL_MASK );
-filter_brush_all_faces g_filter_brush_detail( &g_filter_face_detail );
-
-filter_face_shader_prefix g_filter_face_decals( "textures/decals/" );
-filter_brush_any_face g_filter_brush_decals( &g_filter_face_decals );
-
-
-void BrushFilters_construct(){
- add_brush_filter( g_filter_brush_clip, EXCLUDE_CLIP );
- add_brush_filter( g_filter_brush_clip_q2, EXCLUDE_CLIP );
- add_brush_filter( g_filter_brush_weapclip, EXCLUDE_CLIP );
- add_brush_filter( g_filter_brush_fullclip, EXCLUDE_CLIP );
- add_brush_filter( g_filter_brush_commonclip, EXCLUDE_CLIP );
- add_brush_filter( g_filter_brush_botclip, EXCLUDE_BOTCLIP );
- add_brush_filter( g_filter_brush_caulk, EXCLUDE_CAULK );
- add_brush_filter( g_filter_brush_caulk_ja, EXCLUDE_CAULK );
- add_face_filter( g_filter_face_caulk, EXCLUDE_CAULK );
- add_face_filter( g_filter_face_caulk_ja, EXCLUDE_CAULK );
- add_brush_filter( g_filter_brush_liquids, EXCLUDE_LIQUIDS );
- add_brush_filter( g_filter_brush_liquidsdir, EXCLUDE_LIQUIDS );
- add_brush_filter( g_filter_brush_hint, EXCLUDE_HINTSSKIPS );
- add_brush_filter( g_filter_brush_hintlocal, EXCLUDE_HINTSSKIPS );
- add_brush_filter( g_filter_brush_hint_q2, EXCLUDE_HINTSSKIPS );
- add_brush_filter( g_filter_brush_hint_ja, EXCLUDE_HINTSSKIPS );
- add_brush_filter( g_filter_brush_clusterportal, EXCLUDE_CLUSTERPORTALS );
- add_brush_filter( g_filter_brush_visportal, EXCLUDE_VISPORTALS );
- add_brush_filter( g_filter_brush_areaportal, EXCLUDE_AREAPORTALS );
- add_brush_filter( g_filter_brush_translucent, EXCLUDE_TRANSLUCENT );
- add_brush_filter( g_filter_brush_detail, EXCLUDE_DETAILS );
- add_brush_filter( g_filter_brush_detail, EXCLUDE_STRUCTURAL, true );
- add_brush_filter( g_filter_brush_lightgrid, EXCLUDE_LIGHTGRID );
- add_brush_filter( g_filter_brush_decals, EXCLUDE_DECALS );
-}
-
-#if 0
-
-void normalquantisation_draw(){
- glPointSize( 1 );
- glBegin( GL_POINTS );
- for ( std::size_t i = 0; i <= c_quantise_normal; ++i )
- {
- for ( std::size_t j = 0; j <= c_quantise_normal; ++j )
- {
- Normal3f vertex( normal3f_normalised( Normal3f(
- static_cast<float>( c_quantise_normal - j - i ),
- static_cast<float>( i ),
- static_cast<float>( j )
- ) ) );
- VectorScale( normal3f_to_array( vertex ), 64.f, normal3f_to_array( vertex ) );
- glVertex3fv( normal3f_to_array( vertex ) );
- vertex.x = -vertex.x;
- glVertex3fv( normal3f_to_array( vertex ) );
- }
- }
- glEnd();
-}
-
-class RenderableNormalQuantisation : public OpenGLRenderable
-{
-public:
-void render( RenderStateFlags state ) const {
- normalquantisation_draw();
-}
-};
-
-const float g_test_quantise_normal = 1.f / static_cast<float>( 1 << 3 );
-
-class TestNormalQuantisation
-{
-void check_normal( const Normal3f& normal, const Normal3f& other ){
- spherical_t spherical = spherical_from_normal3f( normal );
- double longditude = RAD2DEG( spherical.longditude );
- double latitude = RAD2DEG( spherical.latitude );
- double x = cos( spherical.longditude ) * sin( spherical.latitude );
- double y = sin( spherical.longditude ) * sin( spherical.latitude );
- double z = cos( spherical.latitude );
-
- ASSERT_MESSAGE( normal3f_dot( normal, other ) > 0.99, "bleh" );
-}
-
-void test_normal( const Normal3f& normal ){
- Normal3f test = normal3f_from_spherical( spherical_from_normal3f( normal ) );
- check_normal( normal, test );
-
- EOctant octant = normal3f_classify_octant( normal );
- Normal3f folded = normal3f_fold_octant( normal, octant );
- ESextant sextant = normal3f_classify_sextant( folded );
- folded = normal3f_fold_sextant( folded, sextant );
-
- double scale = static_cast<float>( c_quantise_normal ) / ( folded.x + folded.y + folded.z );
-
- double zbits = folded.z * scale;
- double ybits = folded.y * scale;
-
- std::size_t zbits_q = static_cast<std::size_t>( zbits );
- std::size_t ybits_q = static_cast<std::size_t>( ybits );
-
- ASSERT_MESSAGE( zbits_q <= ( c_quantise_normal / 8 ) * 3, "bleh" );
- ASSERT_MESSAGE( ybits_q <= ( c_quantise_normal / 2 ), "bleh" );
- ASSERT_MESSAGE( zbits_q + ( ( c_quantise_normal / 2 ) - ybits_q ) <= ( c_quantise_normal / 2 ), "bleh" );
-
- std::size_t y_t = ( zbits_q < ( c_quantise_normal / 4 ) ) ? ybits_q : ( c_quantise_normal / 2 ) - ybits_q;
- std::size_t z_t = ( zbits_q < ( c_quantise_normal / 4 ) ) ? zbits_q : ( c_quantise_normal / 2 ) - zbits_q;
- std::size_t index = ( c_quantise_normal / 4 ) * y_t + z_t;
- ASSERT_MESSAGE( index <= ( c_quantise_normal / 4 ) * ( c_quantise_normal / 2 ), "bleh" );
-
- Normal3f tmp( c_quantise_normal - zbits_q - ybits_q, ybits_q, zbits_q );
- tmp = normal3f_normalised( tmp );
-
- Normal3f unfolded = normal3f_unfold_octant( normal3f_unfold_sextant( tmp, sextant ), octant );
-
- check_normal( normal, unfolded );
-
- double dot = normal3f_dot( normal, unfolded );
- float length = VectorLength( normal3f_to_array( unfolded ) );
- float inv_length = 1 / length;
-
- Normal3f quantised = normal3f_quantised( normal );
- check_normal( normal, quantised );
-}
-void test2( const Normal3f& normal, const Normal3f& other ){
- if ( normal3f_quantised( normal ) != normal3f_quantised( other ) ) {
- int bleh = 0;
- }
-}
-
-static Normal3f normalise( float x, float y, float z ){
- return normal3f_normalised( Normal3f( x, y, z ) );
-}
-
-float vec_rand(){
- return static_cast<float>( rand() - ( RAND_MAX / 2 ) );
-}
-
-Normal3f normal3f_rand(){
- return normalise( vec_rand(), vec_rand(), vec_rand() );
-}
-
-public:
-TestNormalQuantisation(){
- for ( int i = 4096; i > 0; --i )
- test_normal( normal3f_rand() );
-
- test_normal( normalise( 1, 0, 0 ) );
- test_normal( normalise( 0, 1, 0 ) );
- test_normal( normalise( 0, 0, 1 ) );
- test_normal( normalise( 1, 1, 0 ) );
- test_normal( normalise( 1, 0, 1 ) );
- test_normal( normalise( 0, 1, 1 ) );
-
- test_normal( normalise( 10000, 10000, 10000 ) );
- test_normal( normalise( 10000, 10000, 10001 ) );
- test_normal( normalise( 10000, 10000, 10002 ) );
- test_normal( normalise( 10000, 10000, 10010 ) );
- test_normal( normalise( 10000, 10000, 10020 ) );
- test_normal( normalise( 10000, 10000, 10030 ) );
- test_normal( normalise( 10000, 10000, 10100 ) );
- test_normal( normalise( 10000, 10000, 10101 ) );
- test_normal( normalise( 10000, 10000, 10102 ) );
- test_normal( normalise( 10000, 10000, 10200 ) );
- test_normal( normalise( 10000, 10000, 10201 ) );
- test_normal( normalise( 10000, 10000, 10202 ) );
- test_normal( normalise( 10000, 10000, 10203 ) );
- test_normal( normalise( 10000, 10000, 10300 ) );
-
-
- test2( normalise( 10000, 10000, 10000 ), normalise( 10000, 10000, 10001 ) );
- test2( normalise( 10000, 10000, 10001 ), normalise( 10000, 10001, 10000 ) );
-}
-};
-
-TestNormalQuantisation g_testNormalQuantisation;
-
-
-#endif
-
-#if 0
-class TestSelectableObserver : public observer_template<const Selectable&>
-{
-public:
-void notify( const Selectable& arguments ){
- bool bleh = arguments.isSelected();
-}
-};
-
-inline void test_bleh(){
- TestSelectableObserver test;
- ObservableSelectableInstance< SingleObservable< SelectionChangeCallback > > bleh;
- bleh.attach( test );
- bleh.setSelected( true );
- bleh.detach( test );
-}
-
-class TestBleh
-{
-public:
-TestBleh(){
- test_bleh();
-}
-};
-
-const TestBleh testbleh;
-#endif
-
-
-#if 0
-class TestRefcountedString
-{
-public:
-TestRefcountedString(){
- {
- // copy construct
- SmartString string1( "string1" );
- SmartString string2( string1 );
- SmartString string3( string2 );
- }
- {
- // refcounted assignment
- SmartString string1( "string1" );
- SmartString string2( "string2" );
- string1 = string2;
- }
- {
- // copy assignment
- SmartString string1( "string1" );
- SmartString string2( "string2" );
- string1 = string2.c_str();
- }
- {
- // self-assignment
- SmartString string1( "string1" );
- string1 = string1;
- }
- {
- // self-assignment via another reference
- SmartString string1( "string1" );
- SmartString string2( string1 );
- string1 = string2;
- }
-}
-};
-
-const TestRefcountedString g_testRefcountedString;
-
-#endif
-
-void Select_MakeDetail(){
- UndoableCommand undo( "brushSetDetail" );
- Scene_BrushSetDetail_Selected( GlobalSceneGraph(), true );
-}
-
-void Select_MakeStructural(){
- UndoableCommand undo( "brushClearDetail" );
- Scene_BrushSetDetail_Selected( GlobalSceneGraph(), false );
-}
-
-class BrushMakeSided
-{
-std::size_t m_count;
-public:
-BrushMakeSided( std::size_t count )
- : m_count( count ){
-}
-
-void set(){
- Scene_BrushConstructPrefab( GlobalSceneGraph(), eBrushPrism, m_count, TextureBrowser_GetSelectedShader( GlobalTextureBrowser() ) );
-}
-
-typedef MemberCaller<BrushMakeSided, void(), &BrushMakeSided::set> SetCaller;
-};
-
-
-BrushMakeSided g_brushmakesided3( 3 );
-BrushMakeSided g_brushmakesided4( 4 );
-BrushMakeSided g_brushmakesided5( 5 );
-BrushMakeSided g_brushmakesided6( 6 );
-BrushMakeSided g_brushmakesided7( 7 );
-BrushMakeSided g_brushmakesided8( 8 );
-BrushMakeSided g_brushmakesided9( 9 );
-
-inline int axis_for_viewtype( int viewtype ){
- switch ( viewtype )
- {
- case XY:
- return 2;
- case XZ:
- return 1;
- case YZ:
- return 0;
- }
- return 2;
-}
-
-class BrushPrefab
-{
-EBrushPrefab m_type;
-public:
-BrushPrefab( EBrushPrefab type )
- : m_type( type ){
-}
-
-void set(){
- DoSides( m_type, axis_for_viewtype( GetViewAxis() ) );
-}
-
-typedef MemberCaller<BrushPrefab, void(), &BrushPrefab::set> SetCaller;
-};
-
-BrushPrefab g_brushprism( eBrushPrism );
-BrushPrefab g_brushcone( eBrushCone );
-BrushPrefab g_brushsphere( eBrushSphere );
-BrushPrefab g_brushrock( eBrushRock );
-
-
-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<void()> g_texture_lock_status_changed;
-ConstReferenceCaller<bool, void(const Callback<void(bool)> &), PropertyImpl<bool>::Export> g_texdef_movelock_caller( g_brush_texturelock_enabled );
-ToggleItem g_texdef_movelock_item( g_texdef_movelock_caller );
-
-void Texdef_ToggleMoveLock(){
- g_brush_texturelock_enabled = !g_brush_texturelock_enabled;
- g_texdef_movelock_item.update();
- g_texture_lock_status_changed();
-}
-
-
-void Brush_registerCommands(){
- GlobalToggles_insert( "TogTexLock", makeCallbackF(Texdef_ToggleMoveLock), ToggleItem::AddCallbackCaller( g_texdef_movelock_item ), Accelerator( 'T', (GdkModifierType)GDK_SHIFT_MASK ) );
-
- GlobalCommands_insert( "BrushPrism", BrushPrefab::SetCaller( g_brushprism ) );
- GlobalCommands_insert( "BrushCone", BrushPrefab::SetCaller( g_brushcone ) );
- GlobalCommands_insert( "BrushSphere", BrushPrefab::SetCaller( g_brushsphere ) );
- GlobalCommands_insert( "BrushRock", BrushPrefab::SetCaller( g_brushrock ) );
-
- GlobalCommands_insert( "Brush3Sided", BrushMakeSided::SetCaller( g_brushmakesided3 ), Accelerator( '3', (GdkModifierType)GDK_CONTROL_MASK ) );
- GlobalCommands_insert( "Brush4Sided", BrushMakeSided::SetCaller( g_brushmakesided4 ), Accelerator( '4', (GdkModifierType)GDK_CONTROL_MASK ) );
- GlobalCommands_insert( "Brush5Sided", BrushMakeSided::SetCaller( g_brushmakesided5 ), Accelerator( '5', (GdkModifierType)GDK_CONTROL_MASK ) );
- GlobalCommands_insert( "Brush6Sided", BrushMakeSided::SetCaller( g_brushmakesided6 ), Accelerator( '6', (GdkModifierType)GDK_CONTROL_MASK ) );
- GlobalCommands_insert( "Brush7Sided", BrushMakeSided::SetCaller( g_brushmakesided7 ), Accelerator( '7', (GdkModifierType)GDK_CONTROL_MASK ) );
- 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", makeCallbackF(ClipSelected), Accelerator( GDK_KEY_Return ) );
- GlobalCommands_insert( "SplitSelected", makeCallbackF(SplitSelected), Accelerator( GDK_KEY_Return, (GdkModifierType)GDK_SHIFT_MASK ) );
- GlobalCommands_insert( "FlipClip", makeCallbackF(FlipClipper), Accelerator( GDK_KEY_Return, (GdkModifierType)GDK_CONTROL_MASK ) );
-
- GlobalCommands_insert( "MakeDetail", makeCallbackF(Select_MakeDetail), Accelerator( 'M', (GdkModifierType)GDK_CONTROL_MASK ) );
- GlobalCommands_insert( "MakeStructural", makeCallbackF(Select_MakeStructural), Accelerator( 'S', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
-}
-
-void Brush_constructMenu( ui::Menu menu ){
- create_menu_item_with_mnemonic( menu, "Prism...", "BrushPrism" );
- create_menu_item_with_mnemonic( menu, "Cone...", "BrushCone" );
- create_menu_item_with_mnemonic( menu, "Sphere...", "BrushSphere" );
- create_menu_item_with_mnemonic( menu, "Rock...", "BrushRock" );
- menu_separator( menu );
- {
- auto menu_in_menu = create_sub_menu_with_mnemonic( menu, "CSG" );
- if ( g_Layout_enableDetachableMenus.m_value ) {
- menu_tearoff( menu_in_menu );
- }
- create_menu_item_with_mnemonic( menu_in_menu, "CSG _Subtract", "CSGSubtract" );
- create_menu_item_with_mnemonic( menu_in_menu, "CSG _Merge", "CSGMerge" );
- create_menu_item_with_mnemonic( menu_in_menu, "Make _Room", "CSGRoom" );
- create_menu_item_with_mnemonic( menu_in_menu, "CSG _Tool", "CSGTool" );
- }
- menu_separator( menu );
- {
- auto menu_in_menu = create_sub_menu_with_mnemonic( menu, "Clipper" );
- if ( g_Layout_enableDetachableMenus.m_value ) {
- 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" );
- }
- menu_separator( menu );
- create_menu_item_with_mnemonic( menu, "Make detail", "MakeDetail" );
- create_menu_item_with_mnemonic( menu, "Make structural", "MakeStructural" );
-// create_menu_item_with_mnemonic( menu, "Snap selection to _grid", "SnapToGrid" );
-
- create_check_menu_item_with_mnemonic( menu, "Texture Lock", "TogTexLock" );
- menu_separator( menu );
- create_menu_item_with_mnemonic( menu, "Copy Face Texture", "FaceCopyTexture" );
- create_menu_item_with_mnemonic( menu, "Paste Face Texture", "FacePasteTexture" );
-
- command_connect_accelerator( "Brush3Sided" );
- command_connect_accelerator( "Brush4Sided" );
- command_connect_accelerator( "Brush5Sided" );
- command_connect_accelerator( "Brush6Sided" );
- command_connect_accelerator( "Brush7Sided" );
- command_connect_accelerator( "Brush8Sided" );
- command_connect_accelerator( "Brush9Sided" );
-}
+++ /dev/null
-/*
- Copyright (C) 1999-2006 Id Software, Inc. and contributors.
- For a list of contributors, see the accompanying CONTRIBUTORS file.
-
- This file is part of GtkRadiant.
-
- GtkRadiant is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- GtkRadiant is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GtkRadiant; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-//
-// Camera Window
-//
-// Leonardo Zide (leo@lokigames.com)
-//
-
-#include "camwindow.h"
-
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-
-#include "debugging/debugging.h"
-
-#include "iscenegraph.h"
-#include "irender.h"
-#include "igl.h"
-#include "icamera.h"
-#include "cullable.h"
-#include "renderable.h"
-#include "preferencesystem.h"
-
-#include "signal/signal.h"
-#include "container/array.h"
-#include "scenelib.h"
-#include "render.h"
-#include "cmdlib.h"
-#include "math/frustum.h"
-
-#include "gtkutil/widget.h"
-#include "gtkutil/button.h"
-#include "gtkutil/toolbar.h"
-#include "gtkutil/glwidget.h"
-#include "gtkutil/xorrectangle.h"
-#include "gtkmisc.h"
-#include "selection.h"
-#include "mainframe.h"
-#include "preferences.h"
-#include "commands.h"
-#include "xywindow.h"
-#include "windowobservers.h"
-#include "renderstate.h"
-
-#include "timer.h"
-
-Signal0 g_cameraMoved_callbacks;
-
-void AddCameraMovedCallback( const SignalHandler& handler ){
- g_cameraMoved_callbacks.connectLast( handler );
-}
-
-void CameraMovedNotify(){
- g_cameraMoved_callbacks();
-}
-
-
-struct camwindow_globals_private_t
-{
- int m_nMoveSpeed;
- bool m_bCamLinkSpeed;
- int m_nAngleSpeed;
- bool m_bCamInverseMouse;
- bool m_bCamDiscrete;
- bool m_bCubicClipping;
- bool m_showStats;
- int m_nStrafeMode;
-
- camwindow_globals_private_t() :
- m_nMoveSpeed( 100 ),
- m_bCamLinkSpeed( true ),
- m_nAngleSpeed( 3 ),
- m_bCamInverseMouse( false ),
- m_bCamDiscrete( true ),
- m_bCubicClipping( false ),
- m_showStats( true ),
- m_nStrafeMode( 0 ){
- }
-
-};
-
-camwindow_globals_private_t g_camwindow_globals_private;
-
-
-const Matrix4 g_opengl2radiant(
- 0, 0,-1, 0,
- -1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 0, 1
- );
-
-const Matrix4 g_radiant2opengl(
- 0,-1, 0, 0,
- 0, 0, 1, 0,
- -1, 0, 0, 0,
- 0, 0, 0, 1
- );
-
-struct camera_t;
-void Camera_mouseMove( camera_t& camera, int x, int y );
-
-enum camera_draw_mode
-{
- cd_wire,
- cd_solid,
- cd_texture,
- cd_lighting
-};
-
-struct camera_t
-{
- int width, height;
-
- bool timing;
-
- Vector3 origin;
- Vector3 angles;
-
- Vector3 color; // background
-
- Vector3 forward, right; // move matrix (TTimo: used to have up but it was not updated)
- Vector3 vup, vpn, vright; // view matrix (taken from the modelview matrix)
-
- Matrix4 projection;
- Matrix4 modelview;
-
- bool m_strafe; // true when in strafemode toggled by the ctrl-key
- bool m_strafe_forward; // true when in strafemode by ctrl-key and shift is pressed for forward strafing
-
- unsigned int movementflags; // movement flags
- Timer m_keycontrol_timer;
- guint m_keymove_handler;
-
-
- float fieldOfView;
-
- DeferredMotionDelta m_mouseMove;
-
- static void motionDelta( int x, int y, void* data ){
- Camera_mouseMove( *reinterpret_cast<camera_t*>( data ), x, y );
- }
-
- View* m_view;
- Callback<void()> m_update;
-
- static camera_draw_mode draw_mode;
-
- camera_t( View* view, const Callback<void()>& update )
- : width( 0 ),
- height( 0 ),
- timing( false ),
- origin( 0, 0, 0 ),
- angles( 0, 0, 0 ),
- color( 0, 0, 0 ),
- movementflags( 0 ),
- m_keymove_handler( 0 ),
- fieldOfView( 110.0f ),
- m_mouseMove( motionDelta, this ),
- m_view( view ),
- m_update( update ){
- }
-};
-
-camera_draw_mode camera_t::draw_mode = cd_texture;
-
-inline Matrix4 projection_for_camera( float near_z, float far_z, float fieldOfView, int width, int height ){
- const float half_width = static_cast<float>( near_z * tan( degrees_to_radians( fieldOfView * 0.5 ) ) );
- const float half_height = half_width * ( static_cast<float>( height ) / static_cast<float>( width ) );
-
- return matrix4_frustum(
- -half_width,
- half_width,
- -half_height,
- half_height,
- near_z,
- far_z
- );
-}
-
-float Camera_getFarClipPlane( camera_t& camera ){
- return ( g_camwindow_globals_private.m_bCubicClipping ) ? pow( 2.0, ( g_camwindow_globals.m_nCubicScale + 7 ) / 2.0 ) : 32768.0f;
-}
-
-void Camera_updateProjection( camera_t& camera ){
- float farClip = Camera_getFarClipPlane( camera );
- camera.projection = projection_for_camera( farClip / 4096.0f, farClip, camera.fieldOfView, camera.width, camera.height );
-
- camera.m_view->Construct( camera.projection, camera.modelview, camera.width, camera.height );
-}
-
-void Camera_updateVectors( camera_t& camera ){
- for ( int i = 0 ; i < 3 ; i++ )
- {
- camera.vright[i] = camera.modelview[( i << 2 ) + 0];
- camera.vup[i] = camera.modelview[( i << 2 ) + 1];
- camera.vpn[i] = camera.modelview[( i << 2 ) + 2];
- }
-}
-
-void Camera_updateModelview( camera_t& camera ){
- camera.modelview = g_matrix4_identity;
-
- // roll, pitch, yaw
- Vector3 radiant_eulerXYZ( 0, -camera.angles[CAMERA_PITCH], camera.angles[CAMERA_YAW] );
-
- matrix4_translate_by_vec3( camera.modelview, camera.origin );
- matrix4_rotate_by_euler_xyz_degrees( camera.modelview, radiant_eulerXYZ );
- matrix4_multiply_by_matrix4( camera.modelview, g_radiant2opengl );
- matrix4_affine_invert( camera.modelview );
-
- Camera_updateVectors( camera );
-
- camera.m_view->Construct( camera.projection, camera.modelview, camera.width, camera.height );
-}
-
-
-void Camera_Move_updateAxes( camera_t& camera ){
- double ya = degrees_to_radians( camera.angles[CAMERA_YAW] );
-
- // the movement matrix is kept 2d
- camera.forward[0] = static_cast<float>( cos( ya ) );
- camera.forward[1] = static_cast<float>( sin( ya ) );
- camera.forward[2] = 0;
- camera.right[0] = camera.forward[1];
- camera.right[1] = -camera.forward[0];
-}
-
-void Camera_Freemove_updateAxes( camera_t& camera ){
- camera.right = camera.vright;
- camera.forward = vector3_negated( camera.vpn );
-}
-
-const Vector3& Camera_getOrigin( camera_t& camera ){
- return camera.origin;
-}
-
-void Camera_setOrigin( camera_t& camera, const Vector3& origin ){
- camera.origin = origin;
- Camera_updateModelview( camera );
- camera.m_update();
- CameraMovedNotify();
-}
-
-const Vector3& Camera_getAngles( camera_t& camera ){
- return camera.angles;
-}
-
-void Camera_setAngles( camera_t& camera, const Vector3& angles ){
- camera.angles = angles;
- Camera_updateModelview( camera );
- camera.m_update();
- CameraMovedNotify();
-}
-
-
-void Camera_FreeMove( camera_t& camera, int dx, int dy ){
- // free strafe mode, toggled by the ctrl key with optional shift for forward movement
- if ( camera.m_strafe ) {
- float strafespeed = 0.65f;
-
- if ( g_camwindow_globals_private.m_bCamLinkSpeed ) {
- strafespeed = (float)g_camwindow_globals_private.m_nMoveSpeed / 100;
- }
-
- camera.origin -= camera.vright * strafespeed * dx;
- if ( camera.m_strafe_forward ) {
- camera.origin -= camera.vpn * strafespeed * dy;
- }
- else{
- camera.origin += camera.vup * strafespeed * dy;
- }
- }
- else // free rotation
- {
- const float dtime = 0.1f;
-
- if ( g_camwindow_globals_private.m_bCamInverseMouse ) {
- camera.angles[CAMERA_PITCH] -= dy * dtime * g_camwindow_globals_private.m_nAngleSpeed;
- }
- else{
- camera.angles[CAMERA_PITCH] += dy * dtime * g_camwindow_globals_private.m_nAngleSpeed;
- }
-
- camera.angles[CAMERA_YAW] += dx * dtime * g_camwindow_globals_private.m_nAngleSpeed;
-
- if ( camera.angles[CAMERA_PITCH] > 90 ) {
- camera.angles[CAMERA_PITCH] = 90;
- }
- else if ( camera.angles[CAMERA_PITCH] < -90 ) {
- camera.angles[CAMERA_PITCH] = -90;
- }
-
- if ( camera.angles[CAMERA_YAW] >= 360 ) {
- camera.angles[CAMERA_YAW] -= 360;
- }
- else if ( camera.angles[CAMERA_YAW] <= 0 ) {
- camera.angles[CAMERA_YAW] += 360;
- }
- }
-
- Camera_updateModelview( camera );
- Camera_Freemove_updateAxes( camera );
-}
-
-void Cam_MouseControl( camera_t& camera, int x, int y ){
-<<<<<<< HEAD
- float xf = (float)( x - camera.width / 2 ) / ( camera.width / 2 );
- float yf = (float)( y - camera.height / 2 ) / ( camera.height / 2 );
-=======
-// int xl, xh;
-// int yl, yh;
- float xf, yf;
-
- xf = (float)( x - camera.width / 2 ) / ( camera.width / 2 );
- yf = (float)( y - camera.height / 2 ) / ( camera.height / 2 );
-
-// xl = camera.width / 3;
-// xh = xl * 2;
-// yl = camera.height / 3;
-// yh = yl * 2;
->>>>>>> 3a78d902017a780e65f21f12c709aa746dfcab84
-
- xf *= 1.0f - fabsf( yf );
- if ( xf < 0 ) {
- xf += 0.1f;
- if ( xf > 0 ) {
- xf = 0;
- }
- }
- else
- {
- xf -= 0.1f;
- if ( xf < 0 ) {
- xf = 0;
- }
- }
-
- vector3_add( camera.origin, vector3_scaled( camera.forward, yf * 0.1f * g_camwindow_globals_private.m_nMoveSpeed ) );
- camera.angles[CAMERA_YAW] += xf * -0.1f * g_camwindow_globals_private.m_nAngleSpeed;
-
- Camera_updateModelview( camera );
-}
-
-void Camera_mouseMove( camera_t& camera, int x, int y ){
- //globalOutputStream() << "mousemove... ";
- Camera_FreeMove( camera, -x, -y );
- camera.m_update();
- CameraMovedNotify();
-}
-
-const unsigned int MOVE_NONE = 0;
-const unsigned int MOVE_FORWARD = 1 << 0;
-const unsigned int MOVE_BACK = 1 << 1;
-const unsigned int MOVE_ROTRIGHT = 1 << 2;
-const unsigned int MOVE_ROTLEFT = 1 << 3;
-const unsigned int MOVE_STRAFERIGHT = 1 << 4;
-const unsigned int MOVE_STRAFELEFT = 1 << 5;
-const unsigned int MOVE_UP = 1 << 6;
-const unsigned int MOVE_DOWN = 1 << 7;
-const unsigned int MOVE_PITCHUP = 1 << 8;
-const unsigned int MOVE_PITCHDOWN = 1 << 9;
-const unsigned int MOVE_ALL = MOVE_FORWARD | MOVE_BACK | MOVE_ROTRIGHT | MOVE_ROTLEFT | MOVE_STRAFERIGHT | MOVE_STRAFELEFT | MOVE_UP | MOVE_DOWN | MOVE_PITCHUP | MOVE_PITCHDOWN;
-
-void Cam_KeyControl( camera_t& camera, float dtime ){
- // Update angles
- if ( camera.movementflags & MOVE_ROTLEFT ) {
- camera.angles[CAMERA_YAW] += 15 * dtime * g_camwindow_globals_private.m_nAngleSpeed;
- }
- if ( camera.movementflags & MOVE_ROTRIGHT ) {
- camera.angles[CAMERA_YAW] -= 15 * dtime * g_camwindow_globals_private.m_nAngleSpeed;
- }
- if ( camera.movementflags & MOVE_PITCHUP ) {
- camera.angles[CAMERA_PITCH] += 15 * dtime * g_camwindow_globals_private.m_nAngleSpeed;
- if ( camera.angles[CAMERA_PITCH] > 90 ) {
- camera.angles[CAMERA_PITCH] = 90;
- }
- }
- if ( camera.movementflags & MOVE_PITCHDOWN ) {
- camera.angles[CAMERA_PITCH] -= 15 * dtime * g_camwindow_globals_private.m_nAngleSpeed;
- if ( camera.angles[CAMERA_PITCH] < -90 ) {
- camera.angles[CAMERA_PITCH] = -90;
- }
- }
-
- Camera_updateModelview( camera );
- Camera_Freemove_updateAxes( camera );
-
- // Update position
- if ( camera.movementflags & MOVE_FORWARD ) {
- vector3_add( camera.origin, vector3_scaled( camera.forward, dtime * g_camwindow_globals_private.m_nMoveSpeed ) );
- }
- if ( camera.movementflags & MOVE_BACK ) {
- vector3_add( camera.origin, vector3_scaled( camera.forward, -dtime * g_camwindow_globals_private.m_nMoveSpeed ) );
- }
- if ( camera.movementflags & MOVE_STRAFELEFT ) {
- vector3_add( camera.origin, vector3_scaled( camera.right, -dtime * g_camwindow_globals_private.m_nMoveSpeed ) );
- }
- if ( camera.movementflags & MOVE_STRAFERIGHT ) {
- vector3_add( camera.origin, vector3_scaled( camera.right, dtime * g_camwindow_globals_private.m_nMoveSpeed ) );
- }
- if ( camera.movementflags & MOVE_UP ) {
- vector3_add( camera.origin, vector3_scaled( g_vector3_axis_z, dtime * g_camwindow_globals_private.m_nMoveSpeed ) );
- }
- if ( camera.movementflags & MOVE_DOWN ) {
- vector3_add( camera.origin, vector3_scaled( g_vector3_axis_z, -dtime * g_camwindow_globals_private.m_nMoveSpeed ) );
- }
-
- Camera_updateModelview( camera );
-}
-
-void Camera_keyMove( camera_t& camera ){
- camera.m_mouseMove.flush();
-
- //globalOutputStream() << "keymove... ";
- float time_seconds = camera.m_keycontrol_timer.elapsed_msec() / static_cast<float>( msec_per_sec );
- camera.m_keycontrol_timer.start();
- if ( time_seconds > 0.05f ) {
- time_seconds = 0.05f; // 20fps
- }
- Cam_KeyControl( camera, time_seconds * 5.0f );
-
- camera.m_update();
- CameraMovedNotify();
-}
-
-gboolean camera_keymove( gpointer data ){
- Camera_keyMove( *reinterpret_cast<camera_t*>( data ) );
- return TRUE;
-}
-
-void Camera_setMovementFlags( camera_t& camera, unsigned int mask ){
- if ( ( ~camera.movementflags & mask ) != 0 && camera.movementflags == 0 ) {
- camera.m_keymove_handler = g_idle_add( camera_keymove, &camera );
- }
- camera.movementflags |= mask;
-}
-void Camera_clearMovementFlags( camera_t& camera, unsigned int mask ){
- if ( ( camera.movementflags & ~mask ) == 0 && camera.movementflags != 0 ) {
- g_source_remove( camera.m_keymove_handler );
- camera.m_keymove_handler = 0;
- }
- camera.movementflags &= ~mask;
-}
-
-void Camera_MoveForward_KeyDown( camera_t& camera ){
- Camera_setMovementFlags( camera, MOVE_FORWARD );
-}
-void Camera_MoveForward_KeyUp( camera_t& camera ){
- Camera_clearMovementFlags( camera, MOVE_FORWARD );
-}
-void Camera_MoveBack_KeyDown( camera_t& camera ){
- Camera_setMovementFlags( camera, MOVE_BACK );
-}
-void Camera_MoveBack_KeyUp( camera_t& camera ){
- Camera_clearMovementFlags( camera, MOVE_BACK );
-}
-
-void Camera_MoveLeft_KeyDown( camera_t& camera ){
- Camera_setMovementFlags( camera, MOVE_STRAFELEFT );
-}
-void Camera_MoveLeft_KeyUp( camera_t& camera ){
- Camera_clearMovementFlags( camera, MOVE_STRAFELEFT );
-}
-void Camera_MoveRight_KeyDown( camera_t& camera ){
- Camera_setMovementFlags( camera, MOVE_STRAFERIGHT );
-}
-void Camera_MoveRight_KeyUp( camera_t& camera ){
- Camera_clearMovementFlags( camera, MOVE_STRAFERIGHT );
-}
-
-void Camera_MoveUp_KeyDown( camera_t& camera ){
- Camera_setMovementFlags( camera, MOVE_UP );
-}
-void Camera_MoveUp_KeyUp( camera_t& camera ){
- Camera_clearMovementFlags( camera, MOVE_UP );
-}
-void Camera_MoveDown_KeyDown( camera_t& camera ){
- Camera_setMovementFlags( camera, MOVE_DOWN );
-}
-void Camera_MoveDown_KeyUp( camera_t& camera ){
- Camera_clearMovementFlags( camera, MOVE_DOWN );
-}
-
-void Camera_RotateLeft_KeyDown( camera_t& camera ){
- Camera_setMovementFlags( camera, MOVE_ROTLEFT );
-}
-void Camera_RotateLeft_KeyUp( camera_t& camera ){
- Camera_clearMovementFlags( camera, MOVE_ROTLEFT );
-}
-void Camera_RotateRight_KeyDown( camera_t& camera ){
- Camera_setMovementFlags( camera, MOVE_ROTRIGHT );
-}
-void Camera_RotateRight_KeyUp( camera_t& camera ){
- Camera_clearMovementFlags( camera, MOVE_ROTRIGHT );
-}
-
-void Camera_PitchUp_KeyDown( camera_t& camera ){
- Camera_setMovementFlags( camera, MOVE_PITCHUP );
-}
-void Camera_PitchUp_KeyUp( camera_t& camera ){
- Camera_clearMovementFlags( camera, MOVE_PITCHUP );
-}
-void Camera_PitchDown_KeyDown( camera_t& camera ){
- Camera_setMovementFlags( camera, MOVE_PITCHDOWN );
-}
-void Camera_PitchDown_KeyUp( camera_t& camera ){
- Camera_clearMovementFlags( camera, MOVE_PITCHDOWN );
-}
-
-
-typedef ReferenceCaller<camera_t, void(), &Camera_MoveForward_KeyDown> FreeMoveCameraMoveForwardKeyDownCaller;
-typedef ReferenceCaller<camera_t, void(), &Camera_MoveForward_KeyUp> FreeMoveCameraMoveForwardKeyUpCaller;
-typedef ReferenceCaller<camera_t, void(), &Camera_MoveBack_KeyDown> FreeMoveCameraMoveBackKeyDownCaller;
-typedef ReferenceCaller<camera_t, void(), &Camera_MoveBack_KeyUp> FreeMoveCameraMoveBackKeyUpCaller;
-typedef ReferenceCaller<camera_t, void(), &Camera_MoveLeft_KeyDown> FreeMoveCameraMoveLeftKeyDownCaller;
-typedef ReferenceCaller<camera_t, void(), &Camera_MoveLeft_KeyUp> FreeMoveCameraMoveLeftKeyUpCaller;
-typedef ReferenceCaller<camera_t, void(), &Camera_MoveRight_KeyDown> FreeMoveCameraMoveRightKeyDownCaller;
-typedef ReferenceCaller<camera_t, void(), &Camera_MoveRight_KeyUp> FreeMoveCameraMoveRightKeyUpCaller;
-typedef ReferenceCaller<camera_t, void(), &Camera_MoveUp_KeyDown> FreeMoveCameraMoveUpKeyDownCaller;
-typedef ReferenceCaller<camera_t, void(), &Camera_MoveUp_KeyUp> FreeMoveCameraMoveUpKeyUpCaller;
-typedef ReferenceCaller<camera_t, void(), &Camera_MoveDown_KeyDown> FreeMoveCameraMoveDownKeyDownCaller;
-typedef ReferenceCaller<camera_t, void(), &Camera_MoveDown_KeyUp> FreeMoveCameraMoveDownKeyUpCaller;
-
-
-const float SPEED_MOVE = 32;
-const float SPEED_TURN = 22.5;
-const float MIN_CAM_SPEED = 10;
-const float MAX_CAM_SPEED = 610;
-const float CAM_SPEED_STEP = 50;
-
-void Camera_MoveForward_Discrete( camera_t& camera ){
- Camera_Move_updateAxes( camera );
- Camera_setOrigin( camera, vector3_added( Camera_getOrigin( camera ), vector3_scaled( camera.forward, SPEED_MOVE ) ) );
-}
-void Camera_MoveBack_Discrete( camera_t& camera ){
- Camera_Move_updateAxes( camera );
- Camera_setOrigin( camera, vector3_added( Camera_getOrigin( camera ), vector3_scaled( camera.forward, -SPEED_MOVE ) ) );
-}
-
-void Camera_MoveUp_Discrete( camera_t& camera ){
- Vector3 origin( Camera_getOrigin( camera ) );
- origin[2] += SPEED_MOVE;
- Camera_setOrigin( camera, origin );
-}
-void Camera_MoveDown_Discrete( camera_t& camera ){
- Vector3 origin( Camera_getOrigin( camera ) );
- origin[2] -= SPEED_MOVE;
- Camera_setOrigin( camera, origin );
-}
-
-void Camera_MoveLeft_Discrete( camera_t& camera ){
- Camera_Move_updateAxes( camera );
- Camera_setOrigin( camera, vector3_added( Camera_getOrigin( camera ), vector3_scaled( camera.right, -SPEED_MOVE ) ) );
-}
-void Camera_MoveRight_Discrete( camera_t& camera ){
- Camera_Move_updateAxes( camera );
- Camera_setOrigin( camera, vector3_added( Camera_getOrigin( camera ), vector3_scaled( camera.right, SPEED_MOVE ) ) );
-}
-
-void Camera_RotateLeft_Discrete( camera_t& camera ){
- Vector3 angles( Camera_getAngles( camera ) );
- angles[CAMERA_YAW] += SPEED_TURN;
- Camera_setAngles( camera, angles );
-}
-void Camera_RotateRight_Discrete( camera_t& camera ){
- Vector3 angles( Camera_getAngles( camera ) );
- angles[CAMERA_YAW] -= SPEED_TURN;
- Camera_setAngles( camera, angles );
-}
-
-void Camera_PitchUp_Discrete( camera_t& camera ){
- Vector3 angles( Camera_getAngles( camera ) );
- angles[CAMERA_PITCH] += SPEED_TURN;
- if ( angles[CAMERA_PITCH] > 90 ) {
- angles[CAMERA_PITCH] = 90;
- }
- Camera_setAngles( camera, angles );
-}
-void Camera_PitchDown_Discrete( camera_t& camera ){
- Vector3 angles( Camera_getAngles( camera ) );
- angles[CAMERA_PITCH] -= SPEED_TURN;
- if ( angles[CAMERA_PITCH] < -90 ) {
- angles[CAMERA_PITCH] = -90;
- }
- Camera_setAngles( camera, angles );
-}
-
-
-class RadiantCameraView : public CameraView
-{
-camera_t& m_camera;
-View* m_view;
-Callback<void()> m_update;
-public:
-RadiantCameraView( camera_t& camera, View* view, const Callback<void()>& update ) : m_camera( camera ), m_view( view ), m_update( update ){
-}
-void update(){
- m_view->Construct( m_camera.projection, m_camera.modelview, m_camera.width, m_camera.height );
- m_update();
-}
-void setModelview( const Matrix4& modelview ){
- m_camera.modelview = modelview;
- matrix4_multiply_by_matrix4( m_camera.modelview, g_radiant2opengl );
- matrix4_affine_invert( m_camera.modelview );
- Camera_updateVectors( m_camera );
- update();
-}
-void setFieldOfView( float fieldOfView ){
- float farClip = Camera_getFarClipPlane( m_camera );
- m_camera.projection = projection_for_camera( farClip / 4096.0f, farClip, fieldOfView, m_camera.width, m_camera.height );
- update();
-}
-};
-
-
-void Camera_motionDelta( int x, int y, unsigned int state, void* data ){
- camera_t* cam = reinterpret_cast<camera_t*>( data );
-
- cam->m_mouseMove.motion_delta( x, y, state );
-
- switch ( g_camwindow_globals_private.m_nStrafeMode )
- {
- case 0:
- cam->m_strafe = ( state & GDK_CONTROL_MASK ) != 0;
- if ( cam->m_strafe ) {
- cam->m_strafe_forward = ( state & GDK_SHIFT_MASK ) != 0;
- }
- else{
- cam->m_strafe_forward = false;
- }
- break;
- case 1:
- cam->m_strafe = ( state & GDK_CONTROL_MASK ) != 0 && ( state & GDK_SHIFT_MASK ) == 0;
- cam->m_strafe_forward = false;
- break;
- case 2:
- cam->m_strafe = ( state & GDK_CONTROL_MASK ) != 0 && ( state & GDK_SHIFT_MASK ) == 0;
- cam->m_strafe_forward = cam->m_strafe;
- break;
- }
-}
-
-class CamWnd
-{
-View m_view;
-camera_t m_Camera;
-RadiantCameraView m_cameraview;
-#if 0
-int m_PositionDragCursorX;
-int m_PositionDragCursorY;
-#endif
-
-guint m_freemove_handle_focusout;
-
-static Shader* m_state_select1;
-static Shader* m_state_select2;
-
-FreezePointer m_freezePointer;
-
-public:
-ui::GLArea m_gl_widget;
-ui::Window m_parent{ui::null};
-
-SelectionSystemWindowObserver* m_window_observer;
-XORRectangle m_XORRectangle;
-
-DeferredDraw m_deferredDraw;
-DeferredMotion m_deferred_motion;
-
-guint m_selection_button_press_handler;
-guint m_selection_button_release_handler;
-guint m_selection_motion_handler;
-
-guint m_freelook_button_press_handler;
-
-guint m_sizeHandler;
-guint m_exposeHandler;
-
-CamWnd();
-~CamWnd();
-
-bool m_drawing;
-void queue_draw(){
- //ASSERT_MESSAGE(!m_drawing, "CamWnd::queue_draw(): called while draw is already in progress");
- if ( m_drawing ) {
- return;
- }
- //globalOutputStream() << "queue... ";
- m_deferredDraw.draw();
-}
-void draw();
-
-static void captureStates(){
- m_state_select1 = GlobalShaderCache().capture( "$CAM_HIGHLIGHT" );
- m_state_select2 = GlobalShaderCache().capture( "$CAM_OVERLAY" );
-}
-static void releaseStates(){
- GlobalShaderCache().release( "$CAM_HIGHLIGHT" );
- GlobalShaderCache().release( "$CAM_OVERLAY" );
-}
-
-camera_t& getCamera(){
- return m_Camera;
-}
-
-void BenchMark();
-void Cam_ChangeFloor( bool up );
-
-void DisableFreeMove();
-void EnableFreeMove();
-bool m_bFreeMove;
-
-CameraView& getCameraView(){
- return m_cameraview;
-}
-
-private:
-void Cam_Draw();
-};
-
-typedef MemberCaller<CamWnd, void(), &CamWnd::queue_draw> CamWndQueueDraw;
-
-Shader* CamWnd::m_state_select1 = 0;
-Shader* CamWnd::m_state_select2 = 0;
-
-CamWnd* NewCamWnd(){
- return new CamWnd;
-}
-void DeleteCamWnd( CamWnd* camwnd ){
- delete camwnd;
-}
-
-void CamWnd_constructStatic(){
- CamWnd::captureStates();
-}
-
-void CamWnd_destroyStatic(){
- CamWnd::releaseStates();
-}
-
-static CamWnd* g_camwnd = 0;
-
-void GlobalCamera_setCamWnd( CamWnd& camwnd ){
- g_camwnd = &camwnd;
-}
-
-
-ui::GLArea CamWnd_getWidget( CamWnd& camwnd ){
- return camwnd.m_gl_widget;
-}
-
-ui::Window CamWnd_getParent( CamWnd& camwnd ){
- return camwnd.m_parent;
-}
-
-ToggleShown g_camera_shown( true );
-
-void CamWnd_setParent( CamWnd& camwnd, ui::Window parent ){
- camwnd.m_parent = parent;
- g_camera_shown.connect( camwnd.m_parent );
-}
-
-void CamWnd_Update( CamWnd& camwnd ){
- camwnd.queue_draw();
-}
-
-
-
-camwindow_globals_t g_camwindow_globals;
-
-const Vector3& Camera_getOrigin( CamWnd& camwnd ){
- return Camera_getOrigin( camwnd.getCamera() );
-}
-
-void Camera_setOrigin( CamWnd& camwnd, const Vector3& origin ){
- Camera_setOrigin( camwnd.getCamera(), origin );
-}
-
-const Vector3& Camera_getAngles( CamWnd& camwnd ){
- return Camera_getAngles( camwnd.getCamera() );
-}
-
-void Camera_setAngles( CamWnd& camwnd, const Vector3& angles ){
- Camera_setAngles( camwnd.getCamera(), angles );
-}
-
-
-// =============================================================================
-// CamWnd class
-
-gboolean enable_freelook_button_press( ui::Widget widget, GdkEventButton* event, CamWnd* camwnd ){
- if ( event->type == GDK_BUTTON_PRESS && event->button == 3 && modifiers_for_state( event->state ) == c_modifierNone ) {
- camwnd->EnableFreeMove();
- return TRUE;
- }
- return FALSE;
-}
-
-gboolean disable_freelook_button_press( ui::Widget widget, GdkEventButton* event, CamWnd* camwnd ){
- if ( event->type == GDK_BUTTON_PRESS && event->button == 3 && modifiers_for_state( event->state ) == c_modifierNone ) {
- camwnd->DisableFreeMove();
- return TRUE;
- }
- return FALSE;
-}
-
-#if 0
-gboolean mousecontrol_button_press( ui::Widget widget, GdkEventButton* event, CamWnd* camwnd ){
- if ( event->type == GDK_BUTTON_PRESS && event->button == 3 ) {
- Cam_MouseControl( camwnd->getCamera(), event->x, widget->allocation.height - 1 - event->y );
- }
- return FALSE;
-}
-#endif
-
-void camwnd_update_xor_rectangle( CamWnd& self, rect_t area ){
- if ( self.m_gl_widget.visible() ) {
- self.m_XORRectangle.set( rectangle_from_area( area.min, area.max, self.getCamera().width, self.getCamera().height ) );
- }
-}
-
-
-gboolean selection_button_press( ui::Widget widget, GdkEventButton* event, WindowObserver* observer ){
- if ( event->type == GDK_BUTTON_PRESS ) {
- observer->onMouseDown( WindowVector_forDouble( event->x, event->y ), button_for_button( event->button ), modifiers_for_state( event->state ) );
- }
- return FALSE;
-}
-
-gboolean selection_button_release( ui::Widget widget, GdkEventButton* event, WindowObserver* observer ){
- if ( event->type == GDK_BUTTON_RELEASE ) {
- observer->onMouseUp( WindowVector_forDouble( event->x, event->y ), button_for_button( event->button ), modifiers_for_state( event->state ) );
- }
- return FALSE;
-}
-
-void selection_motion( gdouble x, gdouble y, guint state, void* data ){
- //globalOutputStream() << "motion... ";
- reinterpret_cast<WindowObserver*>( data )->onMouseMotion( WindowVector_forDouble( x, y ), modifiers_for_state( state ) );
-}
-
-inline WindowVector windowvector_for_widget_centre( ui::Widget widget ){
- auto allocation = widget.dimensions();
- return WindowVector( static_cast<float>( allocation.width / 2 ), static_cast<float>(allocation.height / 2 ) );
-}
-
-gboolean selection_button_press_freemove( ui::Widget widget, GdkEventButton* event, WindowObserver* observer ){
- if ( event->type == GDK_BUTTON_PRESS ) {
- observer->onMouseDown( windowvector_for_widget_centre( widget ), button_for_button( event->button ), modifiers_for_state( event->state ) );
- }
- return FALSE;
-}
-
-gboolean selection_button_release_freemove( ui::Widget widget, GdkEventButton* event, WindowObserver* observer ){
- if ( event->type == GDK_BUTTON_RELEASE ) {
- observer->onMouseUp( windowvector_for_widget_centre( widget ), button_for_button( event->button ), modifiers_for_state( event->state ) );
- }
- return FALSE;
-}
-
-gboolean selection_motion_freemove( ui::Widget widget, GdkEventMotion *event, WindowObserver* observer ){
- observer->onMouseMotion( windowvector_for_widget_centre( widget ), modifiers_for_state( event->state ) );
- return FALSE;
-}
-
-gboolean wheelmove_scroll( ui::Widget widget, GdkEventScroll* event, CamWnd* camwnd ){
- if ( event->direction == GDK_SCROLL_UP ) {
- Camera_Freemove_updateAxes( camwnd->getCamera() );
- Camera_setOrigin( *camwnd, vector3_added( Camera_getOrigin( *camwnd ), vector3_scaled( camwnd->getCamera().forward, static_cast<float>( g_camwindow_globals_private.m_nMoveSpeed ) ) ) );
- }
- else if ( event->direction == GDK_SCROLL_DOWN ) {
- Camera_Freemove_updateAxes( camwnd->getCamera() );
- Camera_setOrigin( *camwnd, vector3_added( Camera_getOrigin( *camwnd ), vector3_scaled( camwnd->getCamera().forward, -static_cast<float>( g_camwindow_globals_private.m_nMoveSpeed ) ) ) );
- }
-
- return FALSE;
-}
-
-gboolean camera_size_allocate( ui::Widget widget, GtkAllocation* allocation, CamWnd* camwnd ){
- camwnd->getCamera().width = allocation->width;
- camwnd->getCamera().height = allocation->height;
- Camera_updateProjection( camwnd->getCamera() );
- camwnd->m_window_observer->onSizeChanged( camwnd->getCamera().width, camwnd->getCamera().height );
- camwnd->queue_draw();
- return FALSE;
-}
-
-gboolean camera_expose( ui::Widget widget, GdkEventExpose* event, gpointer data ){
- reinterpret_cast<CamWnd*>( data )->draw();
- return FALSE;
-}
-
-void KeyEvent_connect( const char* name ){
- const KeyEvent& keyEvent = GlobalKeyEvents_find( name );
- keydown_accelerators_add( keyEvent.m_accelerator, keyEvent.m_keyDown );
- keyup_accelerators_add( keyEvent.m_accelerator, keyEvent.m_keyUp );
-}
-
-void KeyEvent_disconnect( const char* name ){
- const KeyEvent& keyEvent = GlobalKeyEvents_find( name );
- keydown_accelerators_remove( keyEvent.m_accelerator );
- keyup_accelerators_remove( keyEvent.m_accelerator );
-}
-
-void CamWnd_registerCommands( CamWnd& camwnd ){
-<<<<<<< HEAD
- GlobalKeyEvents_insert( "CameraForward", Accelerator( GDK_KEY_Up ),
- ReferenceCaller<camera_t, void(), Camera_MoveForward_KeyDown>( camwnd.getCamera() ),
- ReferenceCaller<camera_t, void(), Camera_MoveForward_KeyUp>( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraBack", Accelerator( GDK_KEY_Down ),
- ReferenceCaller<camera_t, void(), Camera_MoveBack_KeyDown>( camwnd.getCamera() ),
- ReferenceCaller<camera_t, void(), Camera_MoveBack_KeyUp>( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraLeft", Accelerator( GDK_KEY_Left ),
- ReferenceCaller<camera_t, void(), Camera_RotateLeft_KeyDown>( camwnd.getCamera() ),
- ReferenceCaller<camera_t, void(), Camera_RotateLeft_KeyUp>( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraRight", Accelerator( GDK_KEY_Right ),
- ReferenceCaller<camera_t, void(), Camera_RotateRight_KeyDown>( camwnd.getCamera() ),
- ReferenceCaller<camera_t, void(), Camera_RotateRight_KeyUp>( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraStrafeRight", Accelerator( GDK_KEY_period ),
- ReferenceCaller<camera_t, void(), Camera_MoveRight_KeyDown>( camwnd.getCamera() ),
- ReferenceCaller<camera_t, void(), Camera_MoveRight_KeyUp>( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraStrafeLeft", Accelerator( GDK_KEY_comma ),
- ReferenceCaller<camera_t, void(), Camera_MoveLeft_KeyDown>( camwnd.getCamera() ),
- ReferenceCaller<camera_t, void(), Camera_MoveLeft_KeyUp>( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraUp", Accelerator( 'D' ),
- ReferenceCaller<camera_t, void(), Camera_MoveUp_KeyDown>( camwnd.getCamera() ),
- ReferenceCaller<camera_t, void(), Camera_MoveUp_KeyUp>( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraDown", Accelerator( 'C' ),
- ReferenceCaller<camera_t, void(), Camera_MoveDown_KeyDown>( camwnd.getCamera() ),
- ReferenceCaller<camera_t, void(), Camera_MoveDown_KeyUp>( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraAngleDown", Accelerator( 'A' ),
- ReferenceCaller<camera_t, void(), Camera_PitchDown_KeyDown>( camwnd.getCamera() ),
- ReferenceCaller<camera_t, void(), Camera_PitchDown_KeyUp>( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraAngleUp", Accelerator( 'Z' ),
- ReferenceCaller<camera_t, void(), Camera_PitchUp_KeyDown>( camwnd.getCamera() ),
- ReferenceCaller<camera_t, void(), Camera_PitchUp_KeyUp>( camwnd.getCamera() )
-=======
- GlobalKeyEvents_insert( "CameraForward", accelerator_null(),
- ReferenceCaller<camera_t, Camera_MoveForward_KeyDown>( camwnd.getCamera() ),
- ReferenceCaller<camera_t, Camera_MoveForward_KeyUp>( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraBack", accelerator_null(),
- ReferenceCaller<camera_t, Camera_MoveBack_KeyDown>( camwnd.getCamera() ),
- ReferenceCaller<camera_t, Camera_MoveBack_KeyUp>( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraLeft", accelerator_null(),
- ReferenceCaller<camera_t, Camera_RotateLeft_KeyDown>( camwnd.getCamera() ),
- ReferenceCaller<camera_t, Camera_RotateLeft_KeyUp>( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraRight", accelerator_null(),
- ReferenceCaller<camera_t, Camera_RotateRight_KeyDown>( camwnd.getCamera() ),
- ReferenceCaller<camera_t, Camera_RotateRight_KeyUp>( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraStrafeRight", accelerator_null(),
- ReferenceCaller<camera_t, Camera_MoveRight_KeyDown>( camwnd.getCamera() ),
- ReferenceCaller<camera_t, Camera_MoveRight_KeyUp>( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraStrafeLeft", accelerator_null(),
- ReferenceCaller<camera_t, Camera_MoveLeft_KeyDown>( camwnd.getCamera() ),
- ReferenceCaller<camera_t, Camera_MoveLeft_KeyUp>( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraUp", accelerator_null(),
- ReferenceCaller<camera_t, Camera_MoveUp_KeyDown>( camwnd.getCamera() ),
- ReferenceCaller<camera_t, Camera_MoveUp_KeyUp>( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraDown", accelerator_null(),
- ReferenceCaller<camera_t, Camera_MoveDown_KeyDown>( camwnd.getCamera() ),
- ReferenceCaller<camera_t, Camera_MoveDown_KeyUp>( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraAngleUp", accelerator_null(),
- ReferenceCaller<camera_t, Camera_PitchUp_KeyDown>( camwnd.getCamera() ),
- ReferenceCaller<camera_t, Camera_PitchUp_KeyUp>( camwnd.getCamera() )
->>>>>>> 3a78d902017a780e65f21f12c709aa746dfcab84
- );
- GlobalKeyEvents_insert( "CameraAngleDown", accelerator_null(),
- ReferenceCaller<camera_t, Camera_PitchDown_KeyDown>( camwnd.getCamera() ),
- ReferenceCaller<camera_t, Camera_PitchDown_KeyUp>( camwnd.getCamera() )
- );
-
-<<<<<<< HEAD
- GlobalKeyEvents_insert( "CameraFreeMoveForward", Accelerator( GDK_KEY_Up ),
- FreeMoveCameraMoveForwardKeyDownCaller( camwnd.getCamera() ),
- FreeMoveCameraMoveForwardKeyUpCaller( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraFreeMoveBack", Accelerator( GDK_KEY_Down ),
- FreeMoveCameraMoveBackKeyDownCaller( camwnd.getCamera() ),
- FreeMoveCameraMoveBackKeyUpCaller( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraFreeMoveLeft", Accelerator( GDK_KEY_Left ),
- FreeMoveCameraMoveLeftKeyDownCaller( camwnd.getCamera() ),
- FreeMoveCameraMoveLeftKeyUpCaller( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraFreeMoveRight", Accelerator( GDK_KEY_Right ),
-=======
- GlobalKeyEvents_insert( "CameraFreeMoveForward", accelerator_null(),
- FreeMoveCameraMoveForwardKeyDownCaller( camwnd.getCamera() ),
- FreeMoveCameraMoveForwardKeyUpCaller( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraFreeMoveBack", accelerator_null(),
- FreeMoveCameraMoveBackKeyDownCaller( camwnd.getCamera() ),
- FreeMoveCameraMoveBackKeyUpCaller( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraFreeMoveLeft", accelerator_null(),
- FreeMoveCameraMoveLeftKeyDownCaller( camwnd.getCamera() ),
- FreeMoveCameraMoveLeftKeyUpCaller( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraFreeMoveRight", accelerator_null(),
->>>>>>> 3a78d902017a780e65f21f12c709aa746dfcab84
- FreeMoveCameraMoveRightKeyDownCaller( camwnd.getCamera() ),
- FreeMoveCameraMoveRightKeyUpCaller( camwnd.getCamera() )
- );
-
- GlobalKeyEvents_insert( "CameraFreeMoveForward2", accelerator_null(),
- FreeMoveCameraMoveForwardKeyDownCaller( camwnd.getCamera() ),
- FreeMoveCameraMoveForwardKeyUpCaller( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraFreeMoveBack2", accelerator_null(),
- FreeMoveCameraMoveBackKeyDownCaller( camwnd.getCamera() ),
- FreeMoveCameraMoveBackKeyUpCaller( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraFreeMoveLeft2", accelerator_null(),
- FreeMoveCameraMoveLeftKeyDownCaller( camwnd.getCamera() ),
- FreeMoveCameraMoveLeftKeyUpCaller( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraFreeMoveRight2", accelerator_null(),
- FreeMoveCameraMoveRightKeyDownCaller( camwnd.getCamera() ),
- FreeMoveCameraMoveRightKeyUpCaller( camwnd.getCamera() )
- );
-
-<<<<<<< HEAD
- GlobalKeyEvents_insert( "CameraFreeMoveUp", Accelerator( 'D' ),
- FreeMoveCameraMoveUpKeyDownCaller( camwnd.getCamera() ),
- FreeMoveCameraMoveUpKeyUpCaller( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraFreeMoveDown", Accelerator( 'C' ),
-=======
- GlobalKeyEvents_insert( "CameraFreeMoveUp", accelerator_null(),
- FreeMoveCameraMoveUpKeyDownCaller( camwnd.getCamera() ),
- FreeMoveCameraMoveUpKeyUpCaller( camwnd.getCamera() )
- );
- GlobalKeyEvents_insert( "CameraFreeMoveDown", accelerator_null(),
->>>>>>> 3a78d902017a780e65f21f12c709aa746dfcab84
- FreeMoveCameraMoveDownKeyDownCaller( camwnd.getCamera() ),
- FreeMoveCameraMoveDownKeyUpCaller( camwnd.getCamera() )
- );
-
-<<<<<<< HEAD
- GlobalCommands_insert( "CameraForward", ReferenceCaller<camera_t, void(), Camera_MoveForward_Discrete>( camwnd.getCamera() ), Accelerator( GDK_KEY_Up ) );
- GlobalCommands_insert( "CameraBack", ReferenceCaller<camera_t, void(), Camera_MoveBack_Discrete>( camwnd.getCamera() ), Accelerator( GDK_KEY_Down ) );
- GlobalCommands_insert( "CameraLeft", ReferenceCaller<camera_t, void(), Camera_RotateLeft_Discrete>( camwnd.getCamera() ), Accelerator( GDK_KEY_Left ) );
- GlobalCommands_insert( "CameraRight", ReferenceCaller<camera_t, void(), Camera_RotateRight_Discrete>( camwnd.getCamera() ), Accelerator( GDK_KEY_Right ) );
- GlobalCommands_insert( "CameraStrafeRight", ReferenceCaller<camera_t, void(), Camera_MoveRight_Discrete>( camwnd.getCamera() ), Accelerator( GDK_KEY_period ) );
- GlobalCommands_insert( "CameraStrafeLeft", ReferenceCaller<camera_t, void(), Camera_MoveLeft_Discrete>( camwnd.getCamera() ), Accelerator( GDK_KEY_comma ) );
-
- GlobalCommands_insert( "CameraUp", ReferenceCaller<camera_t, void(), Camera_MoveUp_Discrete>( camwnd.getCamera() ), Accelerator( 'D' ) );
- GlobalCommands_insert( "CameraDown", ReferenceCaller<camera_t, void(), Camera_MoveDown_Discrete>( camwnd.getCamera() ), Accelerator( 'C' ) );
- GlobalCommands_insert( "CameraAngleUp", ReferenceCaller<camera_t, void(), Camera_PitchUp_Discrete>( camwnd.getCamera() ), Accelerator( 'A' ) );
- GlobalCommands_insert( "CameraAngleDown", ReferenceCaller<camera_t, void(), Camera_PitchDown_Discrete>( camwnd.getCamera() ), Accelerator( 'Z' ) );
-=======
- GlobalCommands_insert( "CameraForward", ReferenceCaller<camera_t, Camera_MoveForward_Discrete>( camwnd.getCamera() ) );
- GlobalCommands_insert( "CameraBack", ReferenceCaller<camera_t, Camera_MoveBack_Discrete>( camwnd.getCamera() ) );
- GlobalCommands_insert( "CameraLeft", ReferenceCaller<camera_t, Camera_RotateLeft_Discrete>( camwnd.getCamera() ) );
- GlobalCommands_insert( "CameraRight", ReferenceCaller<camera_t, Camera_RotateRight_Discrete>( camwnd.getCamera() ) );
- GlobalCommands_insert( "CameraStrafeRight", ReferenceCaller<camera_t, Camera_MoveRight_Discrete>( camwnd.getCamera() ) );
- GlobalCommands_insert( "CameraStrafeLeft", ReferenceCaller<camera_t, Camera_MoveLeft_Discrete>( camwnd.getCamera() ) );
-
- GlobalCommands_insert( "CameraUp", ReferenceCaller<camera_t, Camera_MoveUp_Discrete>( camwnd.getCamera() ) );
- GlobalCommands_insert( "CameraDown", ReferenceCaller<camera_t, Camera_MoveDown_Discrete>( camwnd.getCamera() ) );
- GlobalCommands_insert( "CameraAngleUp", ReferenceCaller<camera_t, Camera_PitchUp_Discrete>( camwnd.getCamera() ) );
- GlobalCommands_insert( "CameraAngleDown", ReferenceCaller<camera_t, Camera_PitchDown_Discrete>( camwnd.getCamera() ) );
->>>>>>> 3a78d902017a780e65f21f12c709aa746dfcab84
-}
-
-void CamWnd_Move_Enable( CamWnd& camwnd ){
- KeyEvent_connect( "CameraForward" );
- KeyEvent_connect( "CameraBack" );
- KeyEvent_connect( "CameraLeft" );
- KeyEvent_connect( "CameraRight" );
- KeyEvent_connect( "CameraStrafeRight" );
- KeyEvent_connect( "CameraStrafeLeft" );
- KeyEvent_connect( "CameraUp" );
- KeyEvent_connect( "CameraDown" );
- KeyEvent_connect( "CameraAngleUp" );
- KeyEvent_connect( "CameraAngleDown" );
-}
-
-void CamWnd_Move_Disable( CamWnd& camwnd ){
- KeyEvent_disconnect( "CameraForward" );
- KeyEvent_disconnect( "CameraBack" );
- KeyEvent_disconnect( "CameraLeft" );
- KeyEvent_disconnect( "CameraRight" );
- KeyEvent_disconnect( "CameraStrafeRight" );
- KeyEvent_disconnect( "CameraStrafeLeft" );
- KeyEvent_disconnect( "CameraUp" );
- KeyEvent_disconnect( "CameraDown" );
- KeyEvent_disconnect( "CameraAngleUp" );
- KeyEvent_disconnect( "CameraAngleDown" );
-}
-
-void CamWnd_Move_Discrete_Enable( CamWnd& camwnd ){
- command_connect_accelerator( "CameraForward" );
- command_connect_accelerator( "CameraBack" );
- command_connect_accelerator( "CameraLeft" );
- command_connect_accelerator( "CameraRight" );
- command_connect_accelerator( "CameraStrafeRight" );
- command_connect_accelerator( "CameraStrafeLeft" );
- command_connect_accelerator( "CameraUp" );
- command_connect_accelerator( "CameraDown" );
- command_connect_accelerator( "CameraAngleUp" );
- command_connect_accelerator( "CameraAngleDown" );
-}
-
-void CamWnd_Move_Discrete_Disable( CamWnd& camwnd ){
- command_disconnect_accelerator( "CameraForward" );
- command_disconnect_accelerator( "CameraBack" );
- command_disconnect_accelerator( "CameraLeft" );
- command_disconnect_accelerator( "CameraRight" );
- command_disconnect_accelerator( "CameraStrafeRight" );
- command_disconnect_accelerator( "CameraStrafeLeft" );
- command_disconnect_accelerator( "CameraUp" );
- command_disconnect_accelerator( "CameraDown" );
- command_disconnect_accelerator( "CameraAngleUp" );
- command_disconnect_accelerator( "CameraAngleDown" );
-}
-
-struct CamWnd_Move_Discrete {
- static void Export(const Callback<void(bool)> &returnz) {
- returnz(g_camwindow_globals_private.m_bCamDiscrete);
- }
-
- static void Import(bool value) {
- if (g_camwnd) {
- Import_(*g_camwnd, value);
- } else {
- g_camwindow_globals_private.m_bCamDiscrete = value;
- }
- }
-
- static void Import_(CamWnd &camwnd, bool value) {
- if ( g_camwindow_globals_private.m_bCamDiscrete ) {
- CamWnd_Move_Discrete_Disable( camwnd );
- } else {
- CamWnd_Move_Disable( camwnd );
- }
-
- g_camwindow_globals_private.m_bCamDiscrete = value;
-
- if ( g_camwindow_globals_private.m_bCamDiscrete ) {
- CamWnd_Move_Discrete_Enable( camwnd );
- } else {
- CamWnd_Move_Enable( camwnd );
- }
-}
-};
-
-
-void CamWnd_Add_Handlers_Move( CamWnd& camwnd ){
- camwnd.m_selection_button_press_handler = camwnd.m_gl_widget.connect( "button_press_event", G_CALLBACK( selection_button_press ), camwnd.m_window_observer );
- camwnd.m_selection_button_release_handler = camwnd.m_gl_widget.connect( "button_release_event", G_CALLBACK( selection_button_release ), camwnd.m_window_observer );
- camwnd.m_selection_motion_handler = camwnd.m_gl_widget.connect( "motion_notify_event", G_CALLBACK( DeferredMotion::gtk_motion ), &camwnd.m_deferred_motion );
-
- camwnd.m_freelook_button_press_handler = camwnd.m_gl_widget.connect( "button_press_event", G_CALLBACK( enable_freelook_button_press ), &camwnd );
-
- if ( g_camwindow_globals_private.m_bCamDiscrete ) {
- CamWnd_Move_Discrete_Enable( camwnd );
- }
- else
- {
- CamWnd_Move_Enable( camwnd );
- }
-}
-
-void CamWnd_Remove_Handlers_Move( CamWnd& camwnd ){
- g_signal_handler_disconnect( G_OBJECT( camwnd.m_gl_widget ), camwnd.m_selection_button_press_handler );
- g_signal_handler_disconnect( G_OBJECT( camwnd.m_gl_widget ), camwnd.m_selection_button_release_handler );
- g_signal_handler_disconnect( G_OBJECT( camwnd.m_gl_widget ), camwnd.m_selection_motion_handler );
-
- g_signal_handler_disconnect( G_OBJECT( camwnd.m_gl_widget ), camwnd.m_freelook_button_press_handler );
-
- if ( g_camwindow_globals_private.m_bCamDiscrete ) {
- CamWnd_Move_Discrete_Disable( camwnd );
- }
- else
- {
- CamWnd_Move_Disable( camwnd );
- }
-}
-
-void CamWnd_Add_Handlers_FreeMove( CamWnd& camwnd ){
- camwnd.m_selection_button_press_handler = camwnd.m_gl_widget.connect( "button_press_event", G_CALLBACK( selection_button_press_freemove ), camwnd.m_window_observer );
- camwnd.m_selection_button_release_handler = camwnd.m_gl_widget.connect( "button_release_event", G_CALLBACK( selection_button_release_freemove ), camwnd.m_window_observer );
- camwnd.m_selection_motion_handler = camwnd.m_gl_widget.connect( "motion_notify_event", G_CALLBACK( selection_motion_freemove ), camwnd.m_window_observer );
-
- camwnd.m_freelook_button_press_handler = camwnd.m_gl_widget.connect( "button_press_event", G_CALLBACK( disable_freelook_button_press ), &camwnd );
-
- KeyEvent_connect( "CameraFreeMoveForward" );
- KeyEvent_connect( "CameraFreeMoveBack" );
- KeyEvent_connect( "CameraFreeMoveLeft" );
- KeyEvent_connect( "CameraFreeMoveRight" );
-
- KeyEvent_connect( "CameraFreeMoveForward2" );
- KeyEvent_connect( "CameraFreeMoveBack2" );
- KeyEvent_connect( "CameraFreeMoveLeft2" );
- KeyEvent_connect( "CameraFreeMoveRight2" );
-
- KeyEvent_connect( "CameraFreeMoveUp" );
- KeyEvent_connect( "CameraFreeMoveDown" );
-}
-
-void CamWnd_Remove_Handlers_FreeMove( CamWnd& camwnd ){
- KeyEvent_disconnect( "CameraFreeMoveForward" );
- KeyEvent_disconnect( "CameraFreeMoveBack" );
- KeyEvent_disconnect( "CameraFreeMoveLeft" );
- KeyEvent_disconnect( "CameraFreeMoveRight" );
-
- KeyEvent_disconnect( "CameraFreeMoveForward2" );
- KeyEvent_disconnect( "CameraFreeMoveBack2" );
- KeyEvent_disconnect( "CameraFreeMoveLeft2" );
- KeyEvent_disconnect( "CameraFreeMoveRight2" );
-
- KeyEvent_disconnect( "CameraFreeMoveUp" );
- KeyEvent_disconnect( "CameraFreeMoveDown" );
-
- g_signal_handler_disconnect( G_OBJECT( camwnd.m_gl_widget ), camwnd.m_selection_button_press_handler );
- g_signal_handler_disconnect( G_OBJECT( camwnd.m_gl_widget ), camwnd.m_selection_button_release_handler );
- g_signal_handler_disconnect( G_OBJECT( camwnd.m_gl_widget ), camwnd.m_selection_motion_handler );
-
- g_signal_handler_disconnect( G_OBJECT( camwnd.m_gl_widget ), camwnd.m_freelook_button_press_handler );
-}
-
-CamWnd::CamWnd() :
- m_view( true ),
- m_Camera( &m_view, CamWndQueueDraw( *this ) ),
- m_cameraview( m_Camera, &m_view, ReferenceCaller<CamWnd, void(), CamWnd_Update>( *this ) ),
- m_gl_widget( glwidget_new( TRUE ) ),
- m_window_observer( NewWindowObserver() ),
- m_XORRectangle( m_gl_widget ),
- m_deferredDraw( WidgetQueueDrawCaller( m_gl_widget ) ),
- m_deferred_motion( selection_motion, m_window_observer ),
- m_selection_button_press_handler( 0 ),
- m_selection_button_release_handler( 0 ),
- m_selection_motion_handler( 0 ),
- m_freelook_button_press_handler( 0 ),
- m_drawing( false ){
- m_bFreeMove = false;
-
- GlobalWindowObservers_add( m_window_observer );
- GlobalWindowObservers_connectWidget( m_gl_widget );
-
- m_window_observer->setRectangleDrawCallback( ReferenceCaller<CamWnd, void(rect_t), camwnd_update_xor_rectangle>( *this ) );
- m_window_observer->setView( m_view );
-
- g_object_ref( m_gl_widget._handle );
-
- gtk_widget_set_events( m_gl_widget, GDK_DESTROY | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK );
- gtk_widget_set_can_focus( m_gl_widget, true );
-
- m_sizeHandler = m_gl_widget.connect( "size_allocate", G_CALLBACK( camera_size_allocate ), this );
- m_exposeHandler = m_gl_widget.on_render( G_CALLBACK( camera_expose ), this );
-
- Map_addValidCallback( g_map, DeferredDrawOnMapValidChangedCaller( m_deferredDraw ) );
-
- CamWnd_registerCommands( *this );
-
- CamWnd_Add_Handlers_Move( *this );
-
- m_gl_widget.connect( "scroll_event", G_CALLBACK( wheelmove_scroll ), this );
-
- AddSceneChangeCallback( ReferenceCaller<CamWnd, void(), CamWnd_Update>( *this ) );
-
- PressedButtons_connect( g_pressedButtons, m_gl_widget );
-}
-
-CamWnd::~CamWnd(){
- if ( m_bFreeMove ) {
- DisableFreeMove();
- }
-
- CamWnd_Remove_Handlers_Move( *this );
-
- g_signal_handler_disconnect( G_OBJECT( m_gl_widget ), m_sizeHandler );
- g_signal_handler_disconnect( G_OBJECT( m_gl_widget ), m_exposeHandler );
-
- m_gl_widget.unref();
-
- m_window_observer->release();
-}
-
-class FloorHeightWalker : public scene::Graph::Walker
-{
-float m_current;
-float& m_bestUp;
-float& m_bestDown;
-public:
-FloorHeightWalker( float current, float& bestUp, float& bestDown ) :
- m_current( current ), m_bestUp( bestUp ), m_bestDown( bestDown ){
- bestUp = g_MaxWorldCoord;
- bestDown = -g_MaxWorldCoord;
-}
-bool pre( const scene::Path& path, scene::Instance& instance ) const {
- if ( path.top().get().visible()
- && Node_isBrush( path.top() ) ) { // this node is a floor
- const AABB& aabb = instance.worldAABB();
- float floorHeight = aabb.origin.z() + aabb.extents.z();
- if ( floorHeight > m_current && floorHeight < m_bestUp ) {
- m_bestUp = floorHeight;
- }
- if ( floorHeight < m_current && floorHeight > m_bestDown ) {
- m_bestDown = floorHeight;
- }
- }
- else if( !path.top().get().visible() ){
- return false;
- }
- return true;
-}
-};
-
-void CamWnd::Cam_ChangeFloor( bool up ){
- float current = m_Camera.origin[2] - 48;
- float bestUp;
- float bestDown;
- GlobalSceneGraph().traverse( FloorHeightWalker( current, bestUp, bestDown ) );
-
- if ( up && bestUp != g_MaxWorldCoord ) {
- current = bestUp;
- }
- if ( !up && bestDown != -g_MaxWorldCoord ) {
- current = bestDown;
- }
-
- m_Camera.origin[2] = current + 48;
- Camera_updateModelview( getCamera() );
- CamWnd_Update( *this );
- CameraMovedNotify();
-}
-
-
-#if 0
-
-// button_press
-Sys_GetCursorPos( &m_PositionDragCursorX, &m_PositionDragCursorY );
-
-// motion
-if ( ( m_bFreeMove && ( buttons == ( RAD_CONTROL | RAD_SHIFT ) ) )
- || ( !m_bFreeMove && ( buttons == ( RAD_RBUTTON | RAD_CONTROL ) ) ) ) {
- Cam_PositionDrag();
- CamWnd_Update( camwnd );
- CameraMovedNotify();
- return;
-}
-
-void CamWnd::Cam_PositionDrag(){
- int x, y;
-
- Sys_GetCursorPos( m_gl_widget, &x, &y );
- if ( x != m_PositionDragCursorX || y != m_PositionDragCursorY ) {
- x -= m_PositionDragCursorX;
- vector3_add( m_Camera.origin, vector3_scaled( m_Camera.vright, x ) );
- y -= m_PositionDragCursorY;
- m_Camera.origin[2] -= y;
- Camera_updateModelview();
- CamWnd_Update( camwnd );
- CameraMovedNotify();
-
- Sys_SetCursorPos( m_parent, m_PositionDragCursorX, m_PositionDragCursorY );
- }
-}
-#endif
-
-
-// NOTE TTimo if there's an OS-level focus out of the application
-// then we can release the camera cursor grab
-static gboolean camwindow_freemove_focusout( ui::Widget widget, GdkEventFocus* event, gpointer data ){
- reinterpret_cast<CamWnd*>( data )->DisableFreeMove();
- return FALSE;
-}
-
-void CamWnd::EnableFreeMove(){
- //globalOutputStream() << "EnableFreeMove\n";
-
- ASSERT_MESSAGE( !m_bFreeMove, "EnableFreeMove: free-move was already enabled" );
- m_bFreeMove = true;
- Camera_clearMovementFlags( getCamera(), MOVE_ALL );
-
- CamWnd_Remove_Handlers_Move( *this );
- CamWnd_Add_Handlers_FreeMove( *this );
-
- gtk_window_set_focus( m_parent, m_gl_widget );
- m_freemove_handle_focusout = m_gl_widget.connect( "focus_out_event", G_CALLBACK( camwindow_freemove_focusout ), this );
- m_freezePointer.freeze_pointer( m_parent, m_gl_widget, Camera_motionDelta, &m_Camera );
-
- CamWnd_Update( *this );
-}
-
-void CamWnd::DisableFreeMove(){
- //globalOutputStream() << "DisableFreeMove\n";
-
- ASSERT_MESSAGE( m_bFreeMove, "DisableFreeMove: free-move was not enabled" );
- m_bFreeMove = false;
- Camera_clearMovementFlags( getCamera(), MOVE_ALL );
-
- CamWnd_Remove_Handlers_FreeMove( *this );
- CamWnd_Add_Handlers_Move( *this );
-
- m_freezePointer.unfreeze_pointer( m_parent, true );
- g_signal_handler_disconnect( G_OBJECT( m_gl_widget ), m_freemove_handle_focusout );
-
- CamWnd_Update( *this );
-}
-
-
-#include "renderer.h"
-
-class CamRenderer : public Renderer
-{
-struct state_type
-{
- state_type() : m_highlight( 0 ), m_state( 0 ), m_lights( 0 ){
- }
- unsigned int m_highlight;
- Shader* m_state;
- const LightList* m_lights;
-};
-
-std::vector<state_type> m_state_stack;
-RenderStateFlags m_globalstate;
-Shader* m_state_select0;
-Shader* m_state_select1;
-const Vector3& m_viewer;
-
-public:
-CamRenderer( RenderStateFlags globalstate, Shader* select0, Shader* select1, const Vector3& viewer ) :
- m_globalstate( globalstate ),
- m_state_select0( select0 ),
- m_state_select1( select1 ),
- m_viewer( viewer ){
- ASSERT_NOTNULL( select0 );
- ASSERT_NOTNULL( select1 );
- m_state_stack.push_back( state_type() );
-}
-
-void SetState( Shader* state, EStyle style ){
- ASSERT_NOTNULL( state );
- if ( style == eFullMaterials ) {
- m_state_stack.back().m_state = state;
- }
-}
-EStyle getStyle() const {
- return eFullMaterials;
-}
-void PushState(){
- m_state_stack.push_back( m_state_stack.back() );
-}
-void PopState(){
- ASSERT_MESSAGE( !m_state_stack.empty(), "popping empty stack" );
- m_state_stack.pop_back();
-}
-void Highlight( EHighlightMode mode, bool bEnable = true ){
- ( bEnable )
- ? m_state_stack.back().m_highlight |= mode
- : m_state_stack.back().m_highlight &= ~mode;
-}
-void setLights( const LightList& lights ){
- m_state_stack.back().m_lights = &lights;
-}
-void addRenderable( const OpenGLRenderable& renderable, const Matrix4& world ){
- if ( m_state_stack.back().m_highlight & ePrimitive ) {
- m_state_select0->addRenderable( renderable, world, m_state_stack.back().m_lights );
- }
- if ( m_state_stack.back().m_highlight & eFace ) {
- m_state_select1->addRenderable( renderable, world, m_state_stack.back().m_lights );
- }
-
- m_state_stack.back().m_state->addRenderable( renderable, world, m_state_stack.back().m_lights );
-}
-
-void render( const Matrix4& modelview, const Matrix4& projection ){
- GlobalShaderCache().render( m_globalstate, modelview, projection, m_viewer );
-}
-};
-
-/*
- ==============
- Cam_Draw
- ==============
- */
-/*
-void ShowStatsToggle(){
- g_camwindow_globals_private.m_showStats ^= 1;
-}
-
-void ShowStatsExport( const Callback<void(bool)> &importer ){
- importer( g_camwindow_globals_private.m_showStats );
-}
-
-FreeCaller<void(const Callback<void(bool)>&), ShowStatsExport> g_show_stats_caller;
-Callback<void(const Callback<void(bool)> &)> g_show_stats_callback( g_show_stats_caller );
-ToggleItem g_show_stats( g_show_stats_callback );
-*/
-
-void ShowStatsToggle(){
- g_camwindow_globals_private.m_showStats ^= 1;
-// g_show_stats.update();
- UpdateAllWindows();
-}
-typedef FreeCaller<void(), ShowStatsToggle> ShowStatsToggleCaller;
-void ShowStatsExport( const Callback<void(bool)> & importer ){
- importer( g_camwindow_globals_private.m_showStats );
-}
-typedef FreeCaller<void(const Callback<void(bool)> &), ShowStatsExport> ShowStatsExportCaller;
-
-ShowStatsExportCaller g_show_stats_caller;
-Callback<void(const Callback<void(bool)> &)> g_show_stats_callback( g_show_stats_caller );
-ToggleItem g_show_stats( g_show_stats_callback );
-
-void CamWnd::Cam_Draw(){
- glViewport( 0, 0, m_Camera.width, m_Camera.height );
-#if 0
- GLint viewprt[4];
- glGetIntegerv( GL_VIEWPORT, viewprt );
-#endif
-
- // enable depth buffer writes
- glDepthMask( GL_TRUE );
- glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
-
- Vector3 clearColour( 0, 0, 0 );
- if ( m_Camera.draw_mode != cd_lighting ) {
- clearColour = g_camwindow_globals.color_cameraback;
- }
-
- glClearColor( clearColour[0], clearColour[1], clearColour[2], 0 );
- glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
-
- extern void Renderer_ResetStats();
- Renderer_ResetStats();
- extern void Cull_ResetStats();
- Cull_ResetStats();
-
- glMatrixMode( GL_PROJECTION );
- glLoadMatrixf( reinterpret_cast<const float*>( &m_Camera.projection ) );
-
- glMatrixMode( GL_MODELVIEW );
- glLoadMatrixf( reinterpret_cast<const float*>( &m_Camera.modelview ) );
-
-
- // one directional light source directly behind the viewer
- {
- GLfloat inverse_cam_dir[4], ambient[4], diffuse[4]; //, material[4];
-
- ambient[0] = ambient[1] = ambient[2] = 0.4f;
- ambient[3] = 1.0f;
- diffuse[0] = diffuse[1] = diffuse[2] = 0.4f;
- diffuse[3] = 1.0f;
- //material[0] = material[1] = material[2] = 0.8f;
- //material[3] = 1.0f;
-
- inverse_cam_dir[0] = m_Camera.vpn[0];
- inverse_cam_dir[1] = m_Camera.vpn[1];
- inverse_cam_dir[2] = m_Camera.vpn[2];
- inverse_cam_dir[3] = 0;
-
- glLightfv( GL_LIGHT0, GL_POSITION, inverse_cam_dir );
-
- glLightfv( GL_LIGHT0, GL_AMBIENT, ambient );
- glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuse );
-
- glEnable( GL_LIGHT0 );
- }
-
-
- unsigned int globalstate = RENDER_DEPTHTEST | RENDER_COLOURWRITE | RENDER_DEPTHWRITE | RENDER_ALPHATEST | RENDER_BLEND | RENDER_CULLFACE | RENDER_COLOURARRAY | RENDER_OFFSETLINE | RENDER_POLYGONSMOOTH | RENDER_LINESMOOTH | RENDER_FOG | RENDER_COLOURCHANGE;
- switch ( m_Camera.draw_mode )
- {
- case cd_wire:
- break;
- case cd_solid:
- globalstate |= RENDER_FILL
- | RENDER_LIGHTING
- | RENDER_SMOOTH
- | RENDER_SCALED;
- break;
- case cd_texture:
- globalstate |= RENDER_FILL
- | RENDER_LIGHTING
- | RENDER_TEXTURE
- | RENDER_SMOOTH
- | RENDER_SCALED;
- break;
- case cd_lighting:
- globalstate |= RENDER_FILL
- | RENDER_LIGHTING
- | RENDER_TEXTURE
- | RENDER_SMOOTH
- | RENDER_SCALED
- | RENDER_BUMP
- | RENDER_PROGRAM
- | RENDER_SCREEN;
- break;
- default:
- globalstate = 0;
- break;
- }
-
-// if ( !g_xywindow_globals.m_bNoStipple ) {
- globalstate |= RENDER_LINESTIPPLE | RENDER_POLYGONSTIPPLE;
-// }
-
- {
- CamRenderer renderer( globalstate, m_state_select2, m_state_select1, m_view.getViewer() );
-
- Scene_Render( renderer, m_view );
-
- renderer.render( m_Camera.modelview, m_Camera.projection );
- }
-
- // prepare for 2d stuff
- glColor4f( 1, 1, 1, 1 );
- glDisable( GL_BLEND );
- glMatrixMode( GL_PROJECTION );
- glLoadIdentity();
- glOrtho( 0, (float)m_Camera.width, 0, (float)m_Camera.height, -100, 100 );
- glScalef( 1, -1, 1 );
- glTranslatef( 0, -(float)m_Camera.height, 0 );
- glMatrixMode( GL_MODELVIEW );
- glLoadIdentity();
-
- if ( GlobalOpenGL().GL_1_3() ) {
- glClientActiveTexture( GL_TEXTURE0 );
- glActiveTexture( GL_TEXTURE0 );
- }
-
- glDisableClientState( GL_TEXTURE_COORD_ARRAY );
- glDisableClientState( GL_NORMAL_ARRAY );
- glDisableClientState( GL_COLOR_ARRAY );
-
- glDisable( GL_TEXTURE_2D );
- glDisable( GL_LIGHTING );
- glDisable( GL_COLOR_MATERIAL );
- glDisable( GL_DEPTH_TEST );
- glColor3f( 1.f, 1.f, 1.f );
- glLineWidth( 1 );
-
- // draw the crosshair
- if ( m_bFreeMove ) {
- glBegin( GL_LINES );
- glVertex2f( (float)m_Camera.width / 2.f, (float)m_Camera.height / 2.f + 6 );
- glVertex2f( (float)m_Camera.width / 2.f, (float)m_Camera.height / 2.f + 2 );
- glVertex2f( (float)m_Camera.width / 2.f, (float)m_Camera.height / 2.f - 6 );
- glVertex2f( (float)m_Camera.width / 2.f, (float)m_Camera.height / 2.f - 2 );
- glVertex2f( (float)m_Camera.width / 2.f + 6, (float)m_Camera.height / 2.f );
- glVertex2f( (float)m_Camera.width / 2.f + 2, (float)m_Camera.height / 2.f );
- glVertex2f( (float)m_Camera.width / 2.f - 6, (float)m_Camera.height / 2.f );
- glVertex2f( (float)m_Camera.width / 2.f - 2, (float)m_Camera.height / 2.f );
- glEnd();
- }
-
- if ( g_camwindow_globals_private.m_showStats ) {
- glRasterPos3f( 1.0f, static_cast<float>( m_Camera.height ) - GlobalOpenGL().m_font->getPixelDescent(), 0.0f );
- extern const char* Renderer_GetStats();
- GlobalOpenGL().drawString( Renderer_GetStats() );
-
- glRasterPos3f( 1.0f, static_cast<float>( m_Camera.height ) - GlobalOpenGL().m_font->getPixelDescent() - GlobalOpenGL().m_font->getPixelHeight(), 0.0f );
- extern const char* Cull_GetStats();
- GlobalOpenGL().drawString( Cull_GetStats() );
- }
-
- // bind back to the default texture so that we don't have problems
- // elsewhere using/modifying texture maps between contexts
- glBindTexture( GL_TEXTURE_2D, 0 );
-}
-
-void CamWnd::draw(){
- m_drawing = true;
-
- //globalOutputStream() << "draw...\n";
- if ( glwidget_make_current( m_gl_widget ) != FALSE ) {
- if ( Map_Valid( g_map ) && ScreenUpdates_Enabled() ) {
- GlobalOpenGL_debugAssertNoErrors();
- Cam_Draw();
- GlobalOpenGL_debugAssertNoErrors();
- //qglFinish();
-
- m_XORRectangle.set( rectangle_t() );
- }
-
- glwidget_swap_buffers( m_gl_widget );
- }
-
- m_drawing = false;
-}
-
-void CamWnd::BenchMark(){
- double dStart = Sys_DoubleTime();
- for ( int i = 0 ; i < 100 ; i++ )
- {
- Vector3 angles;
- angles[CAMERA_ROLL] = 0;
- angles[CAMERA_PITCH] = 0;
- angles[CAMERA_YAW] = static_cast<float>( i * ( 360.0 / 100.0 ) );
- Camera_setAngles( *this, angles );
- }
- double dEnd = Sys_DoubleTime();
- globalOutputStream() << FloatFormat( dEnd - dStart, 5, 2 ) << " seconds\n";
-}
-
-
-void GlobalCamera_ResetAngles(){
- CamWnd& camwnd = *g_camwnd;
- Vector3 angles;
- angles[CAMERA_ROLL] = angles[CAMERA_PITCH] = 0;
- angles[CAMERA_YAW] = static_cast<float>( 22.5 * floor( ( Camera_getAngles( camwnd )[CAMERA_YAW] + 11 ) / 22.5 ) );
- Camera_setAngles( camwnd, angles );
-}
-
-#include "select.h"
-
-void GlobalCamera_FocusOnSelected(){
- CamWnd& camwnd = *g_camwnd;
-
- Vector3 angles( Camera_getAngles( camwnd ) );
- Vector3 radangles( degrees_to_radians( angles[0] ), degrees_to_radians( angles[1] ), degrees_to_radians( angles[2] ) );
- Vector3 viewvector;
- viewvector[0] = cos( radangles[1] ) * cos( radangles[0] );
- viewvector[1] = sin( radangles[1] ) * cos( radangles[0] );
- viewvector[2] = sin( radangles[0] );
-
- Vector3 camorigin( Camera_getOrigin( camwnd ) );
-
- AABB aabb( aabb_for_minmax( Select_getWorkZone().d_work_min, Select_getWorkZone().d_work_max ) );
-
- View& view = *( camwnd.getCamera().m_view );
-
- Plane3 frustumPlanes[4];
- frustumPlanes[0] = plane3_translated( view.getFrustum().left, camorigin - aabb.origin );
- frustumPlanes[1] = plane3_translated( view.getFrustum().right, camorigin - aabb.origin );
- frustumPlanes[2] = plane3_translated( view.getFrustum().top, camorigin - aabb.origin );
- frustumPlanes[3] = plane3_translated( view.getFrustum().bottom, camorigin - aabb.origin );
-
- float offset = 64.0f;
-
- Vector3 corners[8];
- aabb_corners( aabb, corners );
-
- for ( size_t i = 0; i < 4; ++i ){
- for ( size_t j = 0; j < 8; ++j ){
- Ray ray( aabb.origin, -viewvector );
- //Plane3 newplane( frustumPlanes[i].normal(), vector3_dot( frustumPlanes[i].normal(), corners[j] - frustumPlanes[i].normal() * 16.0f ) );
- Plane3 newplane( frustumPlanes[i].normal(), vector3_dot( frustumPlanes[i].normal(), corners[j] ) );
- float d = vector3_dot( ray.direction, newplane.normal() );
- if( d != 0 ){
- float s = vector3_dot( newplane.normal() * newplane.dist() - ray.origin, newplane.normal() ) / d;
- offset = std::max( offset, s );
- }
- }
- }
- Camera_setOrigin( camwnd, aabb.origin - viewvector * offset );
-}
-
-void Camera_ChangeFloorUp(){
- CamWnd& camwnd = *g_camwnd;
- camwnd.Cam_ChangeFloor( true );
-}
-
-void Camera_ChangeFloorDown(){
- CamWnd& camwnd = *g_camwnd;
- camwnd.Cam_ChangeFloor( false );
-}
-
-void Camera_CubeIn(){
- CamWnd& camwnd = *g_camwnd;
- g_camwindow_globals.m_nCubicScale--;
- if ( g_camwindow_globals.m_nCubicScale < 1 ) {
- g_camwindow_globals.m_nCubicScale = 1;
- }
- Camera_updateProjection( camwnd.getCamera() );
- CamWnd_Update( camwnd );
- g_pParentWnd->SetGridStatus();
-}
-
-void Camera_CubeOut(){
- CamWnd& camwnd = *g_camwnd;
- g_camwindow_globals.m_nCubicScale++;
- if ( g_camwindow_globals.m_nCubicScale > 23 ) {
- g_camwindow_globals.m_nCubicScale = 23;
- }
- Camera_updateProjection( camwnd.getCamera() );
- CamWnd_Update( camwnd );
- g_pParentWnd->SetGridStatus();
-}
-
-bool Camera_GetFarClip(){
- return g_camwindow_globals_private.m_bCubicClipping;
-}
-
-ConstReferenceCaller<bool, void(const Callback<void(bool)> &), PropertyImpl<bool>::Export> g_getfarclip_caller( g_camwindow_globals_private.m_bCubicClipping );
-ToggleItem g_getfarclip_item( g_getfarclip_caller );
-
-void Camera_SetFarClip( bool value ){
- CamWnd& camwnd = *g_camwnd;
- g_camwindow_globals_private.m_bCubicClipping = value;
- g_getfarclip_item.update();
- Camera_updateProjection( camwnd.getCamera() );
- CamWnd_Update( camwnd );
-}
-
-struct Camera_FarClip {
- static void Export(const Callback<void(bool)> &returnz) {
- returnz(g_camwindow_globals_private.m_bCubicClipping);
- }
-
- static void Import(bool value) {
- Camera_SetFarClip(value);
- }
-};
-
-void Camera_ToggleFarClip(){
- Camera_SetFarClip( !Camera_GetFarClip() );
-}
-
-
-void CamWnd_constructToolbar( ui::Toolbar toolbar ){
- toolbar_append_toggle_button( toolbar, "Cubic clip the camera view (Ctrl + \\)", "view_cubicclipping.png", "ToggleCubicClip" );
-}
-
-void CamWnd_registerShortcuts(){
- toggle_add_accelerator( "ToggleCubicClip" );
-
- if ( g_pGameDescription->mGameType == "doom3" ) {
- command_connect_accelerator( "TogglePreview" );
- }
-
- command_connect_accelerator( "CameraSpeedInc" );
- command_connect_accelerator( "CameraSpeedDec" );
-}
-
-
-void GlobalCamera_Benchmark(){
- CamWnd& camwnd = *g_camwnd;
- camwnd.BenchMark();
-}
-
-void GlobalCamera_Update(){
- CamWnd& camwnd = *g_camwnd;
- CamWnd_Update( camwnd );
-}
-
-camera_draw_mode CamWnd_GetMode(){
- return camera_t::draw_mode;
-}
-void CamWnd_SetMode( camera_draw_mode mode ){
- ShaderCache_setBumpEnabled( mode == cd_lighting );
- camera_t::draw_mode = mode;
- if ( g_camwnd != 0 ) {
- CamWnd_Update( *g_camwnd );
- }
-}
-
-void CamWnd_TogglePreview( void ){
- // gametype must be doom3 for this function to work
- // if the gametype is not doom3 something is wrong with the
- // global command list or somebody else calls this function.
- ASSERT_MESSAGE( g_pGameDescription->mGameType == "doom3", "CamWnd_TogglePreview called although mGameType is not doom3 compatible" );
-
- // switch between textured and lighting mode
- CamWnd_SetMode( ( CamWnd_GetMode() == cd_lighting ) ? cd_texture : cd_lighting );
-}
-
-
-CameraModel* g_camera_model = 0;
-
-void CamWnd_LookThroughCamera( CamWnd& camwnd ){
- if ( g_camera_model != 0 ) {
- CamWnd_Add_Handlers_Move( camwnd );
- g_camera_model->setCameraView( 0, Callback<void()>() );
- g_camera_model = 0;
- Camera_updateModelview( camwnd.getCamera() );
- Camera_updateProjection( camwnd.getCamera() );
- CamWnd_Update( camwnd );
- }
-}
-
-inline CameraModel* Instance_getCameraModel( scene::Instance& instance ){
- return InstanceTypeCast<CameraModel>::cast( instance );
-}
-
-void CamWnd_LookThroughSelected( CamWnd& camwnd ){
- if ( g_camera_model != 0 ) {
- CamWnd_LookThroughCamera( camwnd );
- }
-
- if ( GlobalSelectionSystem().countSelected() != 0 ) {
- scene::Instance& instance = GlobalSelectionSystem().ultimateSelected();
- CameraModel* cameraModel = Instance_getCameraModel( instance );
- if ( cameraModel != 0 ) {
- CamWnd_Remove_Handlers_Move( camwnd );
- g_camera_model = cameraModel;
- g_camera_model->setCameraView( &camwnd.getCameraView(), ReferenceCaller<CamWnd, void(), CamWnd_LookThroughCamera>( camwnd ) );
- }
- }
-}
-
-void GlobalCamera_LookThroughSelected(){
- CamWnd_LookThroughSelected( *g_camwnd );
-}
-
-void GlobalCamera_LookThroughCamera(){
- CamWnd_LookThroughCamera( *g_camwnd );
-}
-
-struct RenderMode {
- static void Export(const Callback<void(int)> &returnz) {
- switch (CamWnd_GetMode()) {
- case cd_wire:
- returnz(0);
- break;
- case cd_solid:
- returnz(1);
- break;
- case cd_texture:
- returnz(2);
- break;
- case cd_lighting:
- returnz(3);
- break;
- }
- }
-
- static void Import(int value) {
- switch (value) {
- case 0:
- CamWnd_SetMode( cd_wire );
- break;
- case 1:
- CamWnd_SetMode( cd_solid );
- break;
- case 2:
- CamWnd_SetMode( cd_texture );
- break;
- case 3:
- CamWnd_SetMode( cd_lighting );
- break;
- default:
- CamWnd_SetMode( cd_texture );
- }
-}
-};
-
-void Camera_constructPreferences( PreferencesPage& page ){
- page.appendSlider( "Movement Speed", g_camwindow_globals_private.m_nMoveSpeed, TRUE, 0, 0, 100, MIN_CAM_SPEED, MAX_CAM_SPEED, 1, 10 );
- page.appendCheckBox( "", "Link strafe speed to movement speed", g_camwindow_globals_private.m_bCamLinkSpeed );
- page.appendSlider( "Rotation Speed", g_camwindow_globals_private.m_nAngleSpeed, TRUE, 0, 0, 3, 1, 180, 1, 10 );
- page.appendCheckBox( "", "Invert mouse vertical axis", g_camwindow_globals_private.m_bCamInverseMouse );
- page.appendCheckBox(
- "", "Discrete movement",
- make_property<CamWnd_Move_Discrete>()
- );
- page.appendCheckBox(
- "", "Enable far-clip plane",
- make_property<Camera_FarClip>()
- );
-
- if ( g_pGameDescription->mGameType == "doom3" ) {
- const char* render_mode[] = { "Wireframe", "Flatshade", "Textured", "Lighting" };
-
- page.appendCombo(
- "Render Mode",
- STRING_ARRAY_RANGE( render_mode ),
- make_property<RenderMode>()
- );
- }
- else
- {
- const char* render_mode[] = { "Wireframe", "Flatshade", "Textured" };
-
- page.appendCombo(
- "Render Mode",
- STRING_ARRAY_RANGE( render_mode ),
- make_property<RenderMode>()
- );
- }
-
- const char* strafe_mode[] = { "Both", "Forward", "Up" };
-
- page.appendCombo(
- "Strafe Mode",
- g_camwindow_globals_private.m_nStrafeMode,
- STRING_ARRAY_RANGE( strafe_mode )
- );
-}
-void Camera_constructPage( PreferenceGroup& group ){
- PreferencesPage page( group.createPage( "Camera", "Camera View Preferences" ) );
- Camera_constructPreferences( page );
-}
-void Camera_registerPreferencesPage(){
- PreferencesDialog_addSettingsPage( makeCallbackF(Camera_constructPage) );
-}
-
-#include "preferencesystem.h"
-#include "stringio.h"
-#include "dialog.h"
-
-void CameraSpeed_increase(){
- if ( g_camwindow_globals_private.m_nMoveSpeed <= ( MAX_CAM_SPEED - CAM_SPEED_STEP - 10 ) ) {
- g_camwindow_globals_private.m_nMoveSpeed += CAM_SPEED_STEP;
- }
- else {
- g_camwindow_globals_private.m_nMoveSpeed = MAX_CAM_SPEED - 10;
- }
-}
-
-void CameraSpeed_decrease(){
- if ( g_camwindow_globals_private.m_nMoveSpeed >= ( MIN_CAM_SPEED + CAM_SPEED_STEP ) ) {
- g_camwindow_globals_private.m_nMoveSpeed -= CAM_SPEED_STEP;
- }
- else {
- g_camwindow_globals_private.m_nMoveSpeed = MIN_CAM_SPEED;
- }
-}
-
-/// \brief Initialisation for things that have the same lifespan as this module.
-void CamWnd_Construct(){
- GlobalCommands_insert( "CenterView", makeCallbackF(GlobalCamera_ResetAngles), Accelerator( GDK_KEY_End ) );
- GlobalCommands_insert( "CameraFocusOnSelected", makeCallbackF( GlobalCamera_FocusOnSelected ), Accelerator( GDK_Tab ) );
-
- GlobalToggles_insert( "ToggleCubicClip", makeCallbackF(Camera_ToggleFarClip), ToggleItem::AddCallbackCaller( g_getfarclip_item ), Accelerator( '\\', (GdkModifierType)GDK_CONTROL_MASK ) );
- GlobalCommands_insert( "CubicClipZoomIn", makeCallbackF(Camera_CubeIn), Accelerator( '[', (GdkModifierType)GDK_CONTROL_MASK ) );
- GlobalCommands_insert( "CubicClipZoomOut", makeCallbackF(Camera_CubeOut), Accelerator( ']', (GdkModifierType)GDK_CONTROL_MASK ) );
-
- GlobalCommands_insert( "UpFloor", makeCallbackF(Camera_ChangeFloorUp), Accelerator( GDK_KEY_Prior ) );
- GlobalCommands_insert( "DownFloor", makeCallbackF(Camera_ChangeFloorDown), Accelerator( GDK_KEY_Next ) );
-
- GlobalToggles_insert( "ToggleCamera", ToggleShown::ToggleCaller( g_camera_shown ), ToggleItem::AddCallbackCaller( g_camera_shown.m_item ), Accelerator( 'C', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
-// GlobalCommands_insert( "LookThroughSelected", makeCallbackF(GlobalCamera_LookThroughSelected) );
-// GlobalCommands_insert( "LookThroughCamera", makeCallbackF(GlobalCamera_LookThroughCamera) );
-
- if ( g_pGameDescription->mGameType == "doom3" ) {
- GlobalCommands_insert( "TogglePreview", makeCallbackF(CamWnd_TogglePreview), Accelerator( GDK_KEY_F3 ) );
- }
-
- GlobalCommands_insert( "CameraSpeedInc", makeCallbackF(CameraSpeed_increase), Accelerator( GDK_KEY_KP_Add, (GdkModifierType)GDK_SHIFT_MASK ) );
- GlobalCommands_insert( "CameraSpeedDec", makeCallbackF(CameraSpeed_decrease), Accelerator( GDK_KEY_KP_Subtract, (GdkModifierType)GDK_SHIFT_MASK ) );
-
- GlobalShortcuts_insert( "CameraForward", Accelerator( GDK_KEY_Up ) );
- GlobalShortcuts_insert( "CameraBack", Accelerator( GDK_KEY_Down ) );
- GlobalShortcuts_insert( "CameraLeft", Accelerator( GDK_KEY_Left ) );
- GlobalShortcuts_insert( "CameraRight", Accelerator( GDK_KEY_Right ) );
- GlobalShortcuts_insert( "CameraStrafeRight", Accelerator( GDK_KEY_period ) );
- GlobalShortcuts_insert( "CameraStrafeLeft", Accelerator( GDK_KEY_comma ) );
-
- GlobalShortcuts_insert( "CameraUp", accelerator_null() );
- GlobalShortcuts_insert( "CameraDown", accelerator_null() );
- GlobalShortcuts_insert( "CameraAngleUp", accelerator_null() );
- GlobalShortcuts_insert( "CameraAngleDown", accelerator_null() );
-
- GlobalShortcuts_insert( "CameraFreeMoveForward", Accelerator( GDK_Up ) );
- GlobalShortcuts_insert( "CameraFreeMoveBack", Accelerator( GDK_Down ) );
- GlobalShortcuts_insert( "CameraFreeMoveLeft", Accelerator( GDK_Left ) );
- GlobalShortcuts_insert( "CameraFreeMoveRight", Accelerator( GDK_Right ) );
-
- GlobalShortcuts_insert( "CameraFreeMoveForward2", Accelerator( GDK_Up ) );
- GlobalShortcuts_insert( "CameraFreeMoveBack2", Accelerator( GDK_Down ) );
- GlobalShortcuts_insert( "CameraFreeMoveLeft2", Accelerator( GDK_Left ) );
- GlobalShortcuts_insert( "CameraFreeMoveRight2", Accelerator( GDK_Right ) );
-
-<<<<<<< HEAD
- GlobalToggles_insert( "ShowStats", makeCallbackF(ShowStatsToggle), ToggleItem::AddCallbackCaller( g_show_stats ) );
-
- GlobalPreferenceSystem().registerPreference( "ShowStats", make_property_string( g_camwindow_globals_private.m_showStats ) );
- GlobalPreferenceSystem().registerPreference( "MoveSpeed", make_property_string( g_camwindow_globals_private.m_nMoveSpeed ) );
- GlobalPreferenceSystem().registerPreference( "CamLinkSpeed", make_property_string( g_camwindow_globals_private.m_bCamLinkSpeed ) );
- GlobalPreferenceSystem().registerPreference( "AngleSpeed", make_property_string( g_camwindow_globals_private.m_nAngleSpeed ) );
- GlobalPreferenceSystem().registerPreference( "CamInverseMouse", make_property_string( g_camwindow_globals_private.m_bCamInverseMouse ) );
- GlobalPreferenceSystem().registerPreference( "CamDiscrete", make_property_string<CamWnd_Move_Discrete>());
- GlobalPreferenceSystem().registerPreference( "CubicClipping", make_property_string( g_camwindow_globals_private.m_bCubicClipping ) );
- GlobalPreferenceSystem().registerPreference( "CubicScale", make_property_string( g_camwindow_globals.m_nCubicScale ) );
- GlobalPreferenceSystem().registerPreference( "SI_Colors4", make_property_string( g_camwindow_globals.color_cameraback ) );
- GlobalPreferenceSystem().registerPreference( "SI_Colors12", make_property_string( g_camwindow_globals.color_selbrushes3d ) );
- GlobalPreferenceSystem().registerPreference( "CameraRenderMode", make_property_string<RenderMode>() );
- GlobalPreferenceSystem().registerPreference( "StrafeMode", make_property_string( g_camwindow_globals_private.m_nStrafeMode ) );
-=======
- GlobalShortcuts_insert( "CameraFreeMoveUp", accelerator_null() );
- GlobalShortcuts_insert( "CameraFreeMoveDown", accelerator_null() );
-
- GlobalToggles_insert( "ShowStats", FreeCaller<ShowStatsToggle>(), ToggleItem::AddCallbackCaller( g_show_stats ) );
-
- GlobalPreferenceSystem().registerPreference( "ShowStats", BoolImportStringCaller( g_camwindow_globals_private.m_showStats ), BoolExportStringCaller( g_camwindow_globals_private.m_showStats ) );
- GlobalPreferenceSystem().registerPreference( "MoveSpeed", IntImportStringCaller( g_camwindow_globals_private.m_nMoveSpeed ), IntExportStringCaller( g_camwindow_globals_private.m_nMoveSpeed ) );
- GlobalPreferenceSystem().registerPreference( "CamLinkSpeed", BoolImportStringCaller( g_camwindow_globals_private.m_bCamLinkSpeed ), BoolExportStringCaller( g_camwindow_globals_private.m_bCamLinkSpeed ) );
- GlobalPreferenceSystem().registerPreference( "AngleSpeed", IntImportStringCaller( g_camwindow_globals_private.m_nAngleSpeed ), IntExportStringCaller( g_camwindow_globals_private.m_nAngleSpeed ) );
- GlobalPreferenceSystem().registerPreference( "CamInverseMouse", BoolImportStringCaller( g_camwindow_globals_private.m_bCamInverseMouse ), BoolExportStringCaller( g_camwindow_globals_private.m_bCamInverseMouse ) );
- GlobalPreferenceSystem().registerPreference( "CamDiscrete", makeBoolStringImportCallback( CamWndMoveDiscreteImportCaller() ), BoolExportStringCaller( g_camwindow_globals_private.m_bCamDiscrete ) );
- GlobalPreferenceSystem().registerPreference( "CubicClipping", BoolImportStringCaller( g_camwindow_globals_private.m_bCubicClipping ), BoolExportStringCaller( g_camwindow_globals_private.m_bCubicClipping ) );
- GlobalPreferenceSystem().registerPreference( "CubicScale", IntImportStringCaller( g_camwindow_globals.m_nCubicScale ), IntExportStringCaller( g_camwindow_globals.m_nCubicScale ) );
- GlobalPreferenceSystem().registerPreference( "SI_Colors4", Vector3ImportStringCaller( g_camwindow_globals.color_cameraback ), Vector3ExportStringCaller( g_camwindow_globals.color_cameraback ) );
- GlobalPreferenceSystem().registerPreference( "SI_Colors12", Vector3ImportStringCaller( g_camwindow_globals.color_selbrushes3d ), Vector3ExportStringCaller( g_camwindow_globals.color_selbrushes3d ) );
- GlobalPreferenceSystem().registerPreference( "CameraRenderMode", makeIntStringImportCallback( RenderModeImportCaller() ), makeIntStringExportCallback( RenderModeExportCaller() ) );
- GlobalPreferenceSystem().registerPreference( "StrafeMode", IntImportStringCaller( g_camwindow_globals_private.m_nStrafeMode ), IntExportStringCaller( g_camwindow_globals_private.m_nStrafeMode ) );
->>>>>>> 3a78d902017a780e65f21f12c709aa746dfcab84
-
- CamWnd_constructStatic();
-
- Camera_registerPreferencesPage();
-}
-void CamWnd_Destroy(){
- CamWnd_destroyStatic();
-}
auto vbox2 = create_dialog_vbox( 4 );
hbox.pack_start( vbox2, TRUE, FALSE, 0 );
{
- auto frame = create_dialog_frame( 0, ui::Shadow::IN );
- vbox2.pack_start( frame, FALSE, FALSE, 0 );
+ //auto frame = create_dialog_frame( 0, ui::Shadow::IN );
+ //vbox2.pack_start( frame, FALSE, FALSE, 0 );
{
auto image = new_local_image( "logo.png" );
image.show();
- frame.add(image);
+ //frame.add(image);
}
}
}
image.show();
window.add(image);
+ if( gtk_image_get_storage_type( image ) == GTK_IMAGE_PIXBUF ){
+ GdkBitmap* mask;
+ GdkPixbuf* pix = gtk_image_get_pixbuf( image );
+ gdk_pixbuf_render_pixmap_and_mask( pix, NULL, &mask, 255 );
+ gtk_widget_shape_combine_mask ( GTK_WIDGET( window ), mask, 0, 0 );
+ }
+
window.dimensions(-1, -1);
window.show();
+++ /dev/null
-/*
- Copyright (C) 1999-2006 Id Software, Inc. and contributors.
- For a list of contributors, see the accompanying CONTRIBUTORS file.
-
- This file is part of GtkRadiant.
-
- GtkRadiant is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- GtkRadiant is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GtkRadiant; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "select.h"
-
-#include <gtk/gtk.h>
-
-#include "debugging/debugging.h"
-
-#include "ientity.h"
-#include "iselection.h"
-#include "iundo.h"
-
-#include <vector>
-
-#include "stream/stringstream.h"
-#include "signal/isignal.h"
-#include "shaderlib.h"
-#include "scenelib.h"
-
-#include "gtkutil/idledraw.h"
-#include "gtkutil/dialog.h"
-#include "gtkutil/widget.h"
-#include "brushmanip.h"
-#include "brush.h"
-#include "patchmanip.h"
-#include "patchdialog.h"
-#include "selection.h"
-#include "texwindow.h"
-#include "gtkmisc.h"
-#include "mainframe.h"
-#include "grid.h"
-#include "map.h"
-#include "entityinspector.h"
-
-
-
-select_workzone_t g_select_workzone;
-
-
-/**
- Loops over all selected brushes and stores their
- world AABBs in the specified array.
- */
-class CollectSelectedBrushesBounds : public SelectionSystem::Visitor
-{
-AABB* m_bounds; // array of AABBs
-Unsigned m_max; // max AABB-elements in array
-Unsigned& m_count; // count of valid AABBs stored in array
-
-public:
-CollectSelectedBrushesBounds( AABB* bounds, Unsigned max, Unsigned& count )
- : m_bounds( bounds ),
- m_max( max ),
- m_count( count ){
- m_count = 0;
-}
-
-void visit( scene::Instance& instance ) const {
- ASSERT_MESSAGE( m_count <= m_max, "Invalid m_count in CollectSelectedBrushesBounds" );
-
- // stop if the array is already full
- if ( m_count == m_max ) {
- return;
- }
-
- Selectable* selectable = Instance_getSelectable( instance );
- if ( ( selectable != 0 )
- && instance.isSelected() ) {
- // brushes only
- if ( Instance_getBrush( instance ) != 0 ) {
- m_bounds[m_count] = instance.worldAABB();
- ++m_count;
- }
- }
-}
-};
-
-/**
- Selects all objects that intersect one of the bounding AABBs.
- The exact intersection-method is specified through TSelectionPolicy
- */
-template<class TSelectionPolicy>
-class SelectByBounds : public scene::Graph::Walker
-{
-AABB* m_aabbs; // selection aabbs
-Unsigned m_count; // number of aabbs in m_aabbs
-TSelectionPolicy policy; // type that contains a custom intersection method aabb<->aabb
-
-public:
-SelectByBounds( AABB* aabbs, Unsigned count )
- : m_aabbs( aabbs ),
- m_count( count ){
-}
-
-bool pre( const scene::Path& path, scene::Instance& instance ) const {
- if( path.top().get().visible() ){
- Selectable* selectable = Instance_getSelectable( instance );
-
- // ignore worldspawn
- Entity* entity = Node_getEntity( path.top() );
- if ( entity ) {
- if ( string_equal( entity->getKeyValue( "classname" ), "worldspawn" ) ) {
- return true;
- }
- }
-
- if ( ( path.size() > 1 ) &&
- ( !path.top().get().isRoot() ) &&
- ( selectable != 0 ) &&
- ( !node_is_group( path.top() ) )
- ) {
- for ( Unsigned i = 0; i < m_count; ++i )
- {
- if ( policy.Evaluate( m_aabbs[i], instance ) ) {
- selectable->setSelected( true );
- }
- }
- }
- }
- else{
- return false;
- }
-
- return true;
-}
-
-/**
- Performs selection operation on the global scenegraph.
- If delete_bounds_src is true, then the objects which were
- used as source for the selection aabbs will be deleted.
- */
-static void DoSelection( bool delete_bounds_src = true ){
- if ( GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive ) {
- // we may not need all AABBs since not all selected objects have to be brushes
- const Unsigned max = (Unsigned)GlobalSelectionSystem().countSelected();
- AABB* aabbs = new AABB[max];
-
- Unsigned count;
- CollectSelectedBrushesBounds collector( aabbs, max, count );
- GlobalSelectionSystem().foreachSelected( collector );
-
- // nothing usable in selection
- if ( !count ) {
- delete[] aabbs;
- return;
- }
-
- // delete selected objects
- if ( delete_bounds_src ) { // see deleteSelection
- UndoableCommand undo( "deleteSelected" );
- Select_Delete();
- }
-
- // select objects with bounds
- GlobalSceneGraph().traverse( SelectByBounds<TSelectionPolicy>( aabbs, count ) );
-
- SceneChangeNotify();
- delete[] aabbs;
- }
-}
-};
-
-/**
- SelectionPolicy for SelectByBounds
- Returns true if box and the AABB of instance intersect
- */
-class SelectionPolicy_Touching
-{
-public:
-bool Evaluate( const AABB& box, scene::Instance& instance ) const {
- const AABB& other( instance.worldAABB() );
- for ( Unsigned i = 0; i < 3; ++i )
- {
- if ( fabsf( box.origin[i] - other.origin[i] ) > ( box.extents[i] + other.extents[i] ) ) {
- return false;
- }
- }
- return true;
-}
-};
-
-/**
- SelectionPolicy for SelectByBounds
- Returns true if the AABB of instance is inside box
- */
-class SelectionPolicy_Inside
-{
-public:
-bool Evaluate( const AABB& box, scene::Instance& instance ) const {
- const AABB& other( instance.worldAABB() );
- for ( Unsigned i = 0; i < 3; ++i )
- {
- if ( fabsf( box.origin[i] - other.origin[i] ) > ( box.extents[i] - other.extents[i] ) ) {
- return false;
- }
- }
- return true;
-}
-};
-
-class DeleteSelected : public scene::Graph::Walker
-{
-mutable bool m_remove;
-mutable bool m_removedChild;
-public:
-DeleteSelected()
- : m_remove( false ), m_removedChild( false ){
-}
-bool pre( const scene::Path& path, scene::Instance& instance ) const {
- m_removedChild = false;
-
- Selectable* selectable = Instance_getSelectable( instance );
- if ( selectable != 0
- && selectable->isSelected()
- && path.size() > 1
- && !path.top().get().isRoot() ) {
- m_remove = true;
-
- return false; // dont traverse into child elements
- }
- return true;
-}
-void post( const scene::Path& path, scene::Instance& instance ) const {
-
- if ( m_removedChild ) {
- m_removedChild = false;
-
- // delete empty entities
- Entity* entity = Node_getEntity( path.top() );
- if ( entity != 0
- && path.top().get_pointer() != Map_FindWorldspawn( g_map )
- && Node_getTraversable( path.top() )->empty() ) {
- Path_deleteTop( path );
- }
- }
-
- // node should be removed
- if ( m_remove ) {
- if ( Node_isEntity( path.parent() ) != 0 ) {
- m_removedChild = true;
- }
-
- m_remove = false;
- Path_deleteTop( path );
- }
-}
-};
-
-void Scene_DeleteSelected( scene::Graph& graph ){
- graph.traverse( DeleteSelected() );
- SceneChangeNotify();
-}
-
-void Select_Delete( void ){
- Scene_DeleteSelected( GlobalSceneGraph() );
-}
-
-class InvertSelectionWalker : public scene::Graph::Walker
-{
-SelectionSystem::EMode m_mode;
-mutable Selectable* m_selectable;
-public:
-InvertSelectionWalker( SelectionSystem::EMode mode )
- : m_mode( mode ), m_selectable( 0 ){
-}
-bool pre( const scene::Path& path, scene::Instance& instance ) const {
- if( !path.top().get().visible() ){
- m_selectable = 0;
- return false;
- }
- Selectable* selectable = Instance_getSelectable( instance );
- if ( selectable ) {
- switch ( m_mode )
- {
- case SelectionSystem::eEntity:
- if ( Node_isEntity( path.top() ) != 0 ) {
- m_selectable = path.top().get().visible() ? selectable : 0;
- }
- break;
- case SelectionSystem::ePrimitive:
- m_selectable = path.top().get().visible() ? selectable : 0;
- break;
- case SelectionSystem::eComponent:
- break;
- }
- }
- return true;
-}
-void post( const scene::Path& path, scene::Instance& instance ) const {
- if ( m_selectable != 0 ) {
- m_selectable->setSelected( !m_selectable->isSelected() );
- m_selectable = 0;
- }
-}
-};
-
-void Scene_Invert_Selection( scene::Graph& graph ){
- graph.traverse( InvertSelectionWalker( GlobalSelectionSystem().Mode() ) );
-}
-
-void Select_Invert(){
- Scene_Invert_Selection( GlobalSceneGraph() );
-}
-
-//interesting printings
-class ExpandSelectionToEntitiesWalker_dbg : public scene::Graph::Walker
-{
-mutable std::size_t m_depth;
-NodeSmartReference worldspawn;
-public:
-ExpandSelectionToEntitiesWalker_dbg() : m_depth( 0 ), worldspawn( Map_FindOrInsertWorldspawn( g_map ) ){
-}
-bool pre( const scene::Path& path, scene::Instance& instance ) const {
- ++m_depth;
- globalOutputStream() << "pre depth_" << m_depth;
- globalOutputStream() << " path.size()_" << path.size();
- if ( path.top().get() == worldspawn )
- globalOutputStream() << " worldspawn";
- if( path.top().get().isRoot() )
- globalOutputStream() << " path.top().get().isRoot()";
- Entity* entity = Node_getEntity( path.top() );
- if ( entity != 0 ){
- globalOutputStream() << " entity!=0";
- if( entity->isContainer() ){
- globalOutputStream() << " entity->isContainer()";
- }
- globalOutputStream() << " classname_" << entity->getKeyValue( "classname" );
- }
- globalOutputStream() << "\n";
-// globalOutputStream() << "" << ;
-// globalOutputStream() << "" << ;
-// globalOutputStream() << "" << ;
-// globalOutputStream() << "" << ;
- return true;
-}
-void post( const scene::Path& path, scene::Instance& instance ) const {
- globalOutputStream() << "post depth_" << m_depth;
- globalOutputStream() << " path.size()_" << path.size();
- if ( path.top().get() == worldspawn )
- globalOutputStream() << " worldspawn";
- if( path.top().get().isRoot() )
- globalOutputStream() << " path.top().get().isRoot()";
- Entity* entity = Node_getEntity( path.top() );
- if ( entity != 0 ){
- globalOutputStream() << " entity!=0";
- if( entity->isContainer() ){
- globalOutputStream() << " entity->isContainer()";
- }
- globalOutputStream() << " classname_" << entity->getKeyValue( "classname" );
- }
- globalOutputStream() << "\n";
- --m_depth;
-}
-};
-
-class ExpandSelectionToEntitiesWalker : public scene::Graph::Walker
-{
-mutable std::size_t m_depth;
-NodeSmartReference worldspawn;
-public:
-ExpandSelectionToEntitiesWalker() : m_depth( 0 ), worldspawn( Map_FindOrInsertWorldspawn( g_map ) ){
-}
-bool pre( const scene::Path& path, scene::Instance& instance ) const {
- ++m_depth;
-
- // ignore worldspawn
-// NodeSmartReference me( path.top().get() );
-// if ( me == worldspawn ) {
-// return false;
-// }
-
- if ( m_depth == 2 ) { // entity depth
- // traverse and select children if any one is selected
- bool beselected = false;
- if ( instance.childSelected() ) {
- beselected = true;
- if( path.top().get() != worldspawn ){
- Instance_setSelected( instance, true );
- }
- }
- return Node_getEntity( path.top() )->isContainer() && beselected;
- }
- else if ( m_depth == 3 ) { // primitive depth
- Instance_setSelected( instance, true );
- return false;
- }
- return true;
-}
-void post( const scene::Path& path, scene::Instance& instance ) const {
- --m_depth;
-}
-};
-
-void Scene_ExpandSelectionToEntities(){
- GlobalSceneGraph().traverse( ExpandSelectionToEntitiesWalker() );
-}
-
-
-namespace
-{
-void Selection_UpdateWorkzone(){
- if ( GlobalSelectionSystem().countSelected() != 0 ) {
- Select_GetBounds( g_select_workzone.d_work_min, g_select_workzone.d_work_max );
- }
-}
-typedef FreeCaller<void(), Selection_UpdateWorkzone> SelectionUpdateWorkzoneCaller;
-
-IdleDraw g_idleWorkzone = IdleDraw( SelectionUpdateWorkzoneCaller() );
-}
-
-const select_workzone_t& Select_getWorkZone(){
- g_idleWorkzone.flush();
- return g_select_workzone;
-}
-
-void UpdateWorkzone_ForSelection(){
- g_idleWorkzone.queueDraw();
-}
-
-// update the workzone to the current selection
-void UpdateWorkzone_ForSelectionChanged( const Selectable& selectable ){
- if ( selectable.isSelected() ) {
- UpdateWorkzone_ForSelection();
- }
-}
-
-void Select_SetShader( const char* shader ){
- if ( GlobalSelectionSystem().Mode() != SelectionSystem::eComponent ) {
- Scene_BrushSetShader_Selected( GlobalSceneGraph(), shader );
- Scene_PatchSetShader_Selected( GlobalSceneGraph(), shader );
- }
- Scene_BrushSetShader_Component_Selected( GlobalSceneGraph(), shader );
-}
-
-void Select_SetTexdef( const TextureProjection& projection ){
- if ( GlobalSelectionSystem().Mode() != SelectionSystem::eComponent ) {
- Scene_BrushSetTexdef_Selected( GlobalSceneGraph(), projection );
- }
- Scene_BrushSetTexdef_Component_Selected( GlobalSceneGraph(), projection );
-}
-
-void Select_SetFlags( const ContentsFlagsValue& flags ){
- if ( GlobalSelectionSystem().Mode() != SelectionSystem::eComponent ) {
- Scene_BrushSetFlags_Selected( GlobalSceneGraph(), flags );
- }
- Scene_BrushSetFlags_Component_Selected( GlobalSceneGraph(), flags );
-}
-
-void Select_GetBounds( Vector3& mins, Vector3& maxs ){
- AABB bounds;
- Scene_BoundsSelected( GlobalSceneGraph(), bounds );
- maxs = vector3_added( bounds.origin, bounds.extents );
- mins = vector3_subtracted( bounds.origin, bounds.extents );
-}
-
-void Select_GetMid( Vector3& mid ){
- AABB bounds;
- Scene_BoundsSelected( GlobalSceneGraph(), bounds );
- mid = vector3_snapped( bounds.origin );
-}
-
-
-void Select_FlipAxis( int axis ){
- Vector3 flip( 1, 1, 1 );
- flip[axis] = -1;
- GlobalSelectionSystem().scaleSelected( flip );
-}
-
-
-void Select_Scale( float x, float y, float z ){
- GlobalSelectionSystem().scaleSelected( Vector3( x, y, z ) );
-}
-
-enum axis_t
-{
- eAxisX = 0,
- eAxisY = 1,
- eAxisZ = 2,
-};
-
-enum sign_t
-{
- eSignPositive = 1,
- eSignNegative = -1,
-};
-
-inline Matrix4 matrix4_rotation_for_axis90( axis_t axis, sign_t sign ){
- switch ( axis )
- {
- case eAxisX:
- if ( sign == eSignPositive ) {
- return matrix4_rotation_for_sincos_x( 1, 0 );
- }
- else
- {
- return matrix4_rotation_for_sincos_x( -1, 0 );
- }
- case eAxisY:
- if ( sign == eSignPositive ) {
- return matrix4_rotation_for_sincos_y( 1, 0 );
- }
- else
- {
- return matrix4_rotation_for_sincos_y( -1, 0 );
- }
- default: //case eAxisZ:
- if ( sign == eSignPositive ) {
- return matrix4_rotation_for_sincos_z( 1, 0 );
- }
- else
- {
- return matrix4_rotation_for_sincos_z( -1, 0 );
- }
- }
-}
-
-inline void matrix4_rotate_by_axis90( Matrix4& matrix, axis_t axis, sign_t sign ){
- matrix4_multiply_by_matrix4( matrix, matrix4_rotation_for_axis90( axis, sign ) );
-}
-
-inline void matrix4_pivoted_rotate_by_axis90( Matrix4& matrix, axis_t axis, sign_t sign, const Vector3& pivotpoint ){
- matrix4_translate_by_vec3( matrix, pivotpoint );
- matrix4_rotate_by_axis90( matrix, axis, sign );
- matrix4_translate_by_vec3( matrix, vector3_negated( pivotpoint ) );
-}
-
-inline Quaternion quaternion_for_axis90( axis_t axis, sign_t sign ){
-#if 1
- switch ( axis )
- {
- case eAxisX:
- if ( sign == eSignPositive ) {
- return Quaternion( c_half_sqrt2f, 0, 0, c_half_sqrt2f );
- }
- else
- {
- return Quaternion( -c_half_sqrt2f, 0, 0, -c_half_sqrt2f );
- }
- case eAxisY:
- if ( sign == eSignPositive ) {
- return Quaternion( 0, c_half_sqrt2f, 0, c_half_sqrt2f );
- }
- else
- {
- return Quaternion( 0, -c_half_sqrt2f, 0, -c_half_sqrt2f );
- }
- default: //case eAxisZ:
- if ( sign == eSignPositive ) {
- return Quaternion( 0, 0, c_half_sqrt2f, c_half_sqrt2f );
- }
- else
- {
- return Quaternion( 0, 0, -c_half_sqrt2f, -c_half_sqrt2f );
- }
- }
-#else
- quaternion_for_matrix4_rotation( matrix4_rotation_for_axis90( (axis_t)axis, ( deg > 0 ) ? eSignPositive : eSignNegative ) );
-#endif
-}
-
-void Select_RotateAxis( int axis, float deg ){
- if ( fabs( deg ) == 90.f ) {
- GlobalSelectionSystem().rotateSelected( quaternion_for_axis90( (axis_t)axis, ( deg > 0 ) ? eSignPositive : eSignNegative ), true );
- }
- else
- {
- switch ( axis )
- {
- case 0:
- GlobalSelectionSystem().rotateSelected( quaternion_for_matrix4_rotation( matrix4_rotation_for_x_degrees( deg ) ), false );
- break;
- case 1:
- GlobalSelectionSystem().rotateSelected( quaternion_for_matrix4_rotation( matrix4_rotation_for_y_degrees( deg ) ), false );
- break;
- case 2:
- GlobalSelectionSystem().rotateSelected( quaternion_for_matrix4_rotation( matrix4_rotation_for_z_degrees( deg ) ), false );
- break;
- }
- }
-}
-
-
-void Select_ShiftTexture( float x, float y ){
- if ( GlobalSelectionSystem().Mode() != SelectionSystem::eComponent ) {
- Scene_BrushShiftTexdef_Selected( GlobalSceneGraph(), x, y );
- Scene_PatchTranslateTexture_Selected( GlobalSceneGraph(), x, y );
- }
- //globalOutputStream() << "shift selected face textures: s=" << x << " t=" << y << '\n';
- Scene_BrushShiftTexdef_Component_Selected( GlobalSceneGraph(), x, y );
-}
-
-void Select_ScaleTexture( float x, float y ){
- if ( GlobalSelectionSystem().Mode() != SelectionSystem::eComponent ) {
- Scene_BrushScaleTexdef_Selected( GlobalSceneGraph(), x, y );
- Scene_PatchScaleTexture_Selected( GlobalSceneGraph(), x, y );
- }
- Scene_BrushScaleTexdef_Component_Selected( GlobalSceneGraph(), x, y );
-}
-
-void Select_RotateTexture( float amt ){
- if ( GlobalSelectionSystem().Mode() != SelectionSystem::eComponent ) {
- Scene_BrushRotateTexdef_Selected( GlobalSceneGraph(), amt );
- Scene_PatchRotateTexture_Selected( GlobalSceneGraph(), amt );
- }
- Scene_BrushRotateTexdef_Component_Selected( GlobalSceneGraph(), amt );
-}
-
-// TTimo modified to handle shader architecture:
-// expects shader names at input, comparison relies on shader names .. texture names no longer relevant
-void FindReplaceTextures( const char* pFind, const char* pReplace, bool bSelected ){
- if ( !texdef_name_valid( pFind ) ) {
- globalErrorStream() << "FindReplaceTextures: invalid texture name: '" << pFind << "', aborted\n";
- return;
- }
- if ( !texdef_name_valid( pReplace ) ) {
- globalErrorStream() << "FindReplaceTextures: invalid texture name: '" << pReplace << "', aborted\n";
- return;
- }
-
- StringOutputStream command;
- command << "textureFindReplace -find " << pFind << " -replace " << pReplace;
- UndoableCommand undo( command.c_str() );
-
- if ( bSelected ) {
- if ( GlobalSelectionSystem().Mode() != SelectionSystem::eComponent ) {
- Scene_BrushFindReplaceShader_Selected( GlobalSceneGraph(), pFind, pReplace );
- Scene_PatchFindReplaceShader_Selected( GlobalSceneGraph(), pFind, pReplace );
- }
- Scene_BrushFindReplaceShader_Component_Selected( GlobalSceneGraph(), pFind, pReplace );
- }
- else
- {
- Scene_BrushFindReplaceShader( GlobalSceneGraph(), pFind, pReplace );
- Scene_PatchFindReplaceShader( GlobalSceneGraph(), pFind, pReplace );
- }
-}
-
-typedef std::vector<const char*> PropertyValues;
-
-bool propertyvalues_contain( const PropertyValues& propertyvalues, const char *str ){
- for ( PropertyValues::const_iterator i = propertyvalues.begin(); i != propertyvalues.end(); ++i )
- {
- if ( string_equal( str, *i ) ) {
- return true;
- }
- }
- return false;
-}
-
-class EntityFindByPropertyValueWalker : public scene::Graph::Walker
-{
-const PropertyValues& m_propertyvalues;
-const char *m_prop;
-const NodeSmartReference worldspawn;
-public:
-EntityFindByPropertyValueWalker( const char *prop, const PropertyValues& propertyvalues )
- : m_propertyvalues( propertyvalues ), m_prop( prop ), worldspawn( Map_FindOrInsertWorldspawn( g_map ) ){
-}
-bool pre( const scene::Path& path, scene::Instance& instance ) const {
- if( !path.top().get().visible() ){
- return false;
- }
- // ignore worldspawn
- if ( path.top().get() == worldspawn ) {
- return false;
- }
-
- Entity* entity = Node_getEntity( path.top() );
- if ( entity != 0 ){
- if( propertyvalues_contain( m_propertyvalues, entity->getKeyValue( m_prop ) ) ) {
- Instance_getSelectable( instance )->setSelected( true );
- return true;
- }
- return false;
- }
- else if( path.size() > 2 && !path.top().get().isRoot() ){
- Selectable* selectable = Instance_getSelectable( instance );
- if( selectable != 0 )
- selectable->setSelected( true );
- }
- return true;
-}
-};
-
-void Scene_EntitySelectByPropertyValues( scene::Graph& graph, const char *prop, const PropertyValues& propertyvalues ){
- graph.traverse( EntityFindByPropertyValueWalker( prop, propertyvalues ) );
-}
-
-class EntityGetSelectedPropertyValuesWalker : public scene::Graph::Walker
-{
-PropertyValues& m_propertyvalues;
-const char *m_prop;
-const NodeSmartReference worldspawn;
-public:
-EntityGetSelectedPropertyValuesWalker( const char *prop, PropertyValues& propertyvalues )
- : m_propertyvalues( propertyvalues ), m_prop( prop ), worldspawn( Map_FindOrInsertWorldspawn( g_map ) ){
-}
-bool pre( const scene::Path& path, scene::Instance& instance ) const {
- Entity* entity = Node_getEntity( path.top() );
- if ( entity != 0 ){
- if( path.top().get() != worldspawn ){
- Selectable* selectable = Instance_getSelectable( instance );
- if ( ( selectable != 0 && selectable->isSelected() ) || instance.childSelected() ) {
- if ( !propertyvalues_contain( m_propertyvalues, entity->getKeyValue( m_prop ) ) ) {
- m_propertyvalues.push_back( entity->getKeyValue( m_prop ) );
- }
- }
- }
- return false;
- }
- return true;
-}
-};
-/*
-class EntityGetSelectedPropertyValuesWalker : public scene::Graph::Walker
-{
-PropertyValues& m_propertyvalues;
-const char *m_prop;
-mutable bool m_selected_children;
-const NodeSmartReference worldspawn;
-public:
-EntityGetSelectedPropertyValuesWalker( const char *prop, PropertyValues& propertyvalues )
- : m_propertyvalues( propertyvalues ), m_prop( prop ), m_selected_children( false ), worldspawn( Map_FindOrInsertWorldspawn( g_map ) ){
-}
-bool pre( const scene::Path& path, scene::Instance& instance ) const {
- Selectable* selectable = Instance_getSelectable( instance );
- if ( selectable != 0
- && selectable->isSelected() ) {
- Entity* entity = Node_getEntity( path.top() );
- if ( entity != 0 ) {
- if ( !propertyvalues_contain( m_propertyvalues, entity->getKeyValue( m_prop ) ) ) {
- m_propertyvalues.push_back( entity->getKeyValue( m_prop ) );
- }
- return false;
- }
- else{
- m_selected_children = true;
- }
- }
- return true;
-}
-void post( const scene::Path& path, scene::Instance& instance ) const {
- Entity* entity = Node_getEntity( path.top() );
- if( entity != 0 && m_selected_children ){
- m_selected_children = false;
- if( path.top().get() == worldspawn )
- return;
- if ( !propertyvalues_contain( m_propertyvalues, entity->getKeyValue( m_prop ) ) ) {
- m_propertyvalues.push_back( entity->getKeyValue( m_prop ) );
- }
- }
-}
-};
-*/
-void Scene_EntityGetPropertyValues( scene::Graph& graph, const char *prop, PropertyValues& propertyvalues ){
- graph.traverse( EntityGetSelectedPropertyValuesWalker( prop, propertyvalues ) );
-}
-
-void Select_AllOfType(){
- if ( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent ) {
- if ( GlobalSelectionSystem().ComponentMode() == SelectionSystem::eFace ) {
- GlobalSelectionSystem().setSelectedAllComponents( false );
- Scene_BrushSelectByShader_Component( GlobalSceneGraph(), TextureBrowser_GetSelectedShader( GlobalTextureBrowser() ) );
- }
- }
- else
- {
- PropertyValues propertyvalues;
- const char *prop = EntityInspector_getCurrentKey();
- if ( !prop || !*prop ) {
- prop = "classname";
- }
- Scene_EntityGetPropertyValues( GlobalSceneGraph(), prop, propertyvalues );
- GlobalSelectionSystem().setSelectedAll( false );
- if ( !propertyvalues.empty() ) {
- Scene_EntitySelectByPropertyValues( GlobalSceneGraph(), prop, propertyvalues );
- }
- else
- {
- Scene_BrushSelectByShader( GlobalSceneGraph(), TextureBrowser_GetSelectedShader( GlobalTextureBrowser() ) );
- Scene_PatchSelectByShader( GlobalSceneGraph(), TextureBrowser_GetSelectedShader( GlobalTextureBrowser() ) );
- }
- }
-}
-
-void Select_Inside( void ){
- SelectByBounds<SelectionPolicy_Inside>::DoSelection();
-}
-
-void Select_Touching( void ){
- SelectByBounds<SelectionPolicy_Touching>::DoSelection( false );
-}
-
-void Select_FitTexture( float horizontal, float vertical ){
- if ( GlobalSelectionSystem().Mode() != SelectionSystem::eComponent ) {
- Scene_BrushFitTexture_Selected( GlobalSceneGraph(), horizontal, vertical );
- }
- Scene_BrushFitTexture_Component_Selected( GlobalSceneGraph(), horizontal, vertical );
-
- SceneChangeNotify();
-}
-
-
-#include "commands.h"
-#include "dialog.h"
-
-inline void hide_node( scene::Node& node, bool hide ){
- hide
- ? node.enable( scene::Node::eHidden )
- : node.disable( scene::Node::eHidden );
-}
-
-bool g_nodes_be_hidden = false;
-
-ConstReferenceCaller<bool, void(const Callback<void(bool)> &), PropertyImpl<bool>::Export> g_hidden_caller( g_nodes_be_hidden );
-
-ToggleItem g_hidden_item( g_hidden_caller );
-
-class HideSelectedWalker : public scene::Graph::Walker
-{
-bool m_hide;
-public:
-HideSelectedWalker( bool hide )
- : m_hide( hide ){
-}
-bool pre( const scene::Path& path, scene::Instance& instance ) const {
- Selectable* selectable = Instance_getSelectable( instance );
- if ( selectable != 0
- && selectable->isSelected() ) {
- g_nodes_be_hidden = m_hide;
- hide_node( path.top(), m_hide );
- }
- return true;
-}
-};
-
-void Scene_Hide_Selected( bool hide ){
- GlobalSceneGraph().traverse( HideSelectedWalker( hide ) );
-}
-
-void Select_Hide(){
- Scene_Hide_Selected( true );
- SceneChangeNotify();
-}
-
-void HideSelected(){
- Select_Hide();
- GlobalSelectionSystem().setSelectedAll( false );
- g_hidden_item.update();
-}
-
-
-class HideAllWalker : public scene::Graph::Walker
-{
-bool m_hide;
-public:
-HideAllWalker( bool hide )
- : m_hide( hide ){
-}
-bool pre( const scene::Path& path, scene::Instance& instance ) const {
- hide_node( path.top(), m_hide );
- return true;
-}
-};
-
-void Scene_Hide_All( bool hide ){
- GlobalSceneGraph().traverse( HideAllWalker( hide ) );
-}
-
-void Select_ShowAllHidden(){
- Scene_Hide_All( false );
- SceneChangeNotify();
- g_nodes_be_hidden = false;
- g_hidden_item.update();
-}
-
-
-void Selection_Flipx(){
- UndoableCommand undo( "mirrorSelected -axis x" );
- Select_FlipAxis( 0 );
-}
-
-void Selection_Flipy(){
- UndoableCommand undo( "mirrorSelected -axis y" );
- Select_FlipAxis( 1 );
-}
-
-void Selection_Flipz(){
- UndoableCommand undo( "mirrorSelected -axis z" );
- Select_FlipAxis( 2 );
-}
-
-void Selection_Rotatex(){
- UndoableCommand undo( "rotateSelected -axis x -angle -90" );
- Select_RotateAxis( 0,-90 );
-}
-
-void Selection_Rotatey(){
- UndoableCommand undo( "rotateSelected -axis y -angle 90" );
- Select_RotateAxis( 1, 90 );
-}
-
-void Selection_Rotatez(){
- UndoableCommand undo( "rotateSelected -axis z -angle -90" );
- Select_RotateAxis( 2,-90 );
-}
-#include "xywindow.h"
-void Selection_FlipHorizontally(){
- VIEWTYPE viewtype = GlobalXYWnd_getCurrentViewType();
- switch ( viewtype )
- {
- case XY:
- case XZ:
- Selection_Flipx();
- break;
- default:
- Selection_Flipy();
- break;
- }
-}
-
-void Selection_FlipVertically(){
- VIEWTYPE viewtype = GlobalXYWnd_getCurrentViewType();
- switch ( viewtype )
- {
- case XZ:
- case YZ:
- Selection_Flipz();
- break;
- default:
- Selection_Flipy();
- break;
- }
-}
-
-void Selection_RotateClockwise(){
- UndoableCommand undo( "rotateSelected Clockwise 90" );
- VIEWTYPE viewtype = GlobalXYWnd_getCurrentViewType();
- switch ( viewtype )
- {
- case XY:
- Select_RotateAxis( 2, -90 );
- break;
- case XZ:
- Select_RotateAxis( 1, 90 );
- break;
- default:
- Select_RotateAxis( 0, -90 );
- break;
- }
-}
-
-void Selection_RotateAnticlockwise(){
- UndoableCommand undo( "rotateSelected Anticlockwise 90" );
- VIEWTYPE viewtype = GlobalXYWnd_getCurrentViewType();
- switch ( viewtype )
- {
- case XY:
- Select_RotateAxis( 2, 90 );
- break;
- case XZ:
- Select_RotateAxis( 1, -90 );
- break;
- default:
- Select_RotateAxis( 0, 90 );
- break;
- }
-
-}
-
-
-
-void Select_registerCommands(){
- GlobalCommands_insert( "ShowHidden", makeCallbackF( Select_ShowAllHidden ), Accelerator( 'H', (GdkModifierType)GDK_SHIFT_MASK ) );
- GlobalToggles_insert( "HideSelected", makeCallbackF( HideSelected ), ToggleItem::AddCallbackCaller( g_hidden_item ), Accelerator( 'H' ) );
-
- GlobalCommands_insert( "MirrorSelectionX", makeCallbackF( Selection_Flipx ) );
- GlobalCommands_insert( "RotateSelectionX", makeCallbackF( Selection_Rotatex ) );
- GlobalCommands_insert( "MirrorSelectionY", makeCallbackF( Selection_Flipy ) );
- GlobalCommands_insert( "RotateSelectionY", makeCallbackF( Selection_Rotatey ) );
- GlobalCommands_insert( "MirrorSelectionZ", makeCallbackF( Selection_Flipz ) );
- GlobalCommands_insert( "RotateSelectionZ", makeCallbackF( Selection_Rotatez ) );
-
- GlobalCommands_insert( "MirrorSelectionHorizontally", makeCallbackF( Selection_FlipHorizontally ) );
- GlobalCommands_insert( "MirrorSelectionVertically", makeCallbackF( Selection_FlipVertically ) );
-
- GlobalCommands_insert( "RotateSelectionClockwise", makeCallbackF( Selection_RotateClockwise ) );
- GlobalCommands_insert( "RotateSelectionAnticlockwise", makeCallbackF( Selection_RotateAnticlockwise ) );
-}
-
-
-void Nudge( int nDim, float fNudge ){
- Vector3 translate( 0, 0, 0 );
- translate[nDim] = fNudge;
-
- GlobalSelectionSystem().translateSelected( translate );
-}
-
-void Selection_NudgeZ( float amount ){
- StringOutputStream command;
- command << "nudgeSelected -axis z -amount " << amount;
- UndoableCommand undo( command.c_str() );
-
- Nudge( 2, amount );
-}
-
-void Selection_MoveDown(){
- Selection_NudgeZ( -GetGridSize() );
-}
-
-void Selection_MoveUp(){
- Selection_NudgeZ( GetGridSize() );
-}
-
-void SceneSelectionChange( const Selectable& selectable ){
- SceneChangeNotify();
-}
-
-SignalHandlerId Selection_boundsChanged;
-
-void Selection_construct(){
- typedef FreeCaller<void(const Selectable&), SceneSelectionChange> SceneSelectionChangeCaller;
- GlobalSelectionSystem().addSelectionChangeCallback( SceneSelectionChangeCaller() );
- typedef FreeCaller<void(const Selectable&), UpdateWorkzone_ForSelectionChanged> UpdateWorkzoneForSelectionChangedCaller;
- GlobalSelectionSystem().addSelectionChangeCallback( UpdateWorkzoneForSelectionChangedCaller() );
- typedef FreeCaller<void(), UpdateWorkzone_ForSelection> UpdateWorkzoneForSelectionCaller;
- Selection_boundsChanged = GlobalSceneGraph().addBoundsChangedCallback( UpdateWorkzoneForSelectionCaller() );
-}
-
-void Selection_destroy(){
- GlobalSceneGraph().removeBoundsChangedCallback( Selection_boundsChanged );
-}
-
-
-#include "gtkdlgs.h"
-#include <gdk/gdkkeysyms.h>
-
-
-inline Quaternion quaternion_for_euler_xyz_degrees( const Vector3& eulerXYZ ){
-#if 0
- return quaternion_for_matrix4_rotation( matrix4_rotation_for_euler_xyz_degrees( eulerXYZ ) );
-#elif 0
- return quaternion_multiplied_by_quaternion(
- quaternion_multiplied_by_quaternion(
- quaternion_for_z( degrees_to_radians( eulerXYZ[2] ) ),
- quaternion_for_y( degrees_to_radians( eulerXYZ[1] ) )
- ),
- quaternion_for_x( degrees_to_radians( eulerXYZ[0] ) )
- );
-#elif 1
- double cx = cos( degrees_to_radians( eulerXYZ[0] * 0.5 ) );
- double sx = sin( degrees_to_radians( eulerXYZ[0] * 0.5 ) );
- double cy = cos( degrees_to_radians( eulerXYZ[1] * 0.5 ) );
- double sy = sin( degrees_to_radians( eulerXYZ[1] * 0.5 ) );
- double cz = cos( degrees_to_radians( eulerXYZ[2] * 0.5 ) );
- double sz = sin( degrees_to_radians( eulerXYZ[2] * 0.5 ) );
-
- return Quaternion(
- cz * cy * sx - sz * sy * cx,
- cz * sy * cx + sz * cy * sx,
- sz * cy * cx - cz * sy * sx,
- cz * cy * cx + sz * sy * sx
- );
-#endif
-}
-
-struct RotateDialog
-{
- ui::SpinButton x{ui::null};
- ui::SpinButton y{ui::null};
- ui::SpinButton z{ui::null};
- ui::Window window{ui::null};
-};
-
-static gboolean rotatedlg_apply( ui::Widget widget, RotateDialog* rotateDialog ){
- Vector3 eulerXYZ;
-
- gtk_spin_button_update ( rotateDialog->x );
- gtk_spin_button_update ( rotateDialog->y );
- gtk_spin_button_update ( rotateDialog->z );
- eulerXYZ[0] = static_cast<float>( gtk_spin_button_get_value( rotateDialog->x ) );
- eulerXYZ[1] = static_cast<float>( gtk_spin_button_get_value( rotateDialog->y ) );
- eulerXYZ[2] = static_cast<float>( gtk_spin_button_get_value( rotateDialog->z ) );
-
- StringOutputStream command;
- command << "rotateSelectedEulerXYZ -x " << eulerXYZ[0] << " -y " << eulerXYZ[1] << " -z " << eulerXYZ[2];
- UndoableCommand undo( command.c_str() );
-
- GlobalSelectionSystem().rotateSelected( quaternion_for_euler_xyz_degrees( eulerXYZ ), false );
- return TRUE;
-}
-
-static gboolean rotatedlg_cancel( ui::Widget widget, RotateDialog* rotateDialog ){
- rotateDialog->window.hide();
-
- gtk_spin_button_set_value( rotateDialog->x, 0.0f ); // reset to 0 on close
- gtk_spin_button_set_value( rotateDialog->y, 0.0f );
- gtk_spin_button_set_value( rotateDialog->z, 0.0f );
-
- return TRUE;
-}
-
-static gboolean rotatedlg_ok( ui::Widget widget, RotateDialog* rotateDialog ){
- rotatedlg_apply( widget, rotateDialog );
-// rotatedlg_cancel( widget, rotateDialog );
- rotateDialog->window.hide();
- return TRUE;
-}
-
-static gboolean rotatedlg_delete( ui::Widget widget, GdkEventAny *event, RotateDialog* rotateDialog ){
- rotatedlg_cancel( widget, rotateDialog );
- return TRUE;
-}
-
-RotateDialog g_rotate_dialog;
-void DoRotateDlg(){
- if ( !g_rotate_dialog.window ) {
- g_rotate_dialog.window = MainFrame_getWindow().create_dialog_window("Arbitrary rotation", G_CALLBACK(rotatedlg_delete ), &g_rotate_dialog );
-
- auto accel = ui::AccelGroup(ui::New);
- g_rotate_dialog.window.add_accel_group( accel );
-
- {
- auto hbox = create_dialog_hbox( 4, 4 );
- g_rotate_dialog.window.add(hbox);
- {
- auto table = create_dialog_table( 3, 2, 4, 4 );
- hbox.pack_start( table, TRUE, TRUE, 0 );
- {
- ui::Widget label = ui::Label( " X " );
- label.show();
- table.attach(label, {0, 1, 0, 1}, {0, 0});
- }
- {
- ui::Widget label = ui::Label( " Y " );
- label.show();
- table.attach(label, {0, 1, 1, 2}, {0, 0});
- }
- {
- ui::Widget label = ui::Label( " Z " );
- label.show();
- table.attach(label, {0, 1, 2, 3}, {0, 0});
- }
- {
-<<<<<<< HEAD
- auto adj = ui::Adjustment( 0, -359, 359, 1, 10, 0 );
- auto spin = ui::SpinButton( adj, 1, 0 );
- spin.show();
- table.attach(spin, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0});
- spin.dimensions(64, -1);
-=======
- GtkAdjustment* adj = GTK_ADJUSTMENT( gtk_adjustment_new( 0, -359, 359, 1, 10, 0 ) );
- GtkSpinButton* spin = GTK_SPIN_BUTTON( gtk_spin_button_new( adj, 1, 1 ) );
- gtk_widget_show( GTK_WIDGET( spin ) );
- gtk_table_attach( table, GTK_WIDGET( spin ), 1, 2, 0, 1,
- (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
- (GtkAttachOptions) ( 0 ), 0, 0 );
- gtk_widget_set_size_request( GTK_WIDGET( spin ), 64, -1 );
->>>>>>> 3a78d902017a780e65f21f12c709aa746dfcab84
- gtk_spin_button_set_wrap( spin, TRUE );
-
- gtk_widget_grab_focus( spin );
-
- g_rotate_dialog.x = spin;
- }
- {
-<<<<<<< HEAD
- auto adj = ui::Adjustment( 0, -359, 359, 1, 10, 0 );
- auto spin = ui::SpinButton( adj, 1, 0 );
- spin.show();
- table.attach(spin, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0});
- spin.dimensions(64, -1);
-=======
- GtkAdjustment* adj = GTK_ADJUSTMENT( gtk_adjustment_new( 0, -359, 359, 1, 10, 0 ) );
- GtkSpinButton* spin = GTK_SPIN_BUTTON( gtk_spin_button_new( adj, 1, 1 ) );
- gtk_widget_show( GTK_WIDGET( spin ) );
- gtk_table_attach( table, GTK_WIDGET( spin ), 1, 2, 1, 2,
- (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
- (GtkAttachOptions) ( 0 ), 0, 0 );
- gtk_widget_set_size_request( GTK_WIDGET( spin ), 64, -1 );
->>>>>>> 3a78d902017a780e65f21f12c709aa746dfcab84
- gtk_spin_button_set_wrap( spin, TRUE );
-
- g_rotate_dialog.y = spin;
- }
- {
-<<<<<<< HEAD
- auto adj = ui::Adjustment( 0, -359, 359, 1, 10, 0 );
- auto spin = ui::SpinButton( adj, 1, 0 );
- spin.show();
- table.attach(spin, {1, 2, 2, 3}, {GTK_EXPAND | GTK_FILL, 0});
- spin.dimensions(64, -1);
-=======
- GtkAdjustment* adj = GTK_ADJUSTMENT( gtk_adjustment_new( 0, -359, 359, 1, 10, 0 ) );
- GtkSpinButton* spin = GTK_SPIN_BUTTON( gtk_spin_button_new( adj, 1, 1 ) );
- gtk_widget_show( GTK_WIDGET( spin ) );
- gtk_table_attach( table, GTK_WIDGET( spin ), 1, 2, 2, 3,
- (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
- (GtkAttachOptions) ( 0 ), 0, 0 );
- gtk_widget_set_size_request( GTK_WIDGET( spin ), 64, -1 );
->>>>>>> 3a78d902017a780e65f21f12c709aa746dfcab84
- gtk_spin_button_set_wrap( spin, TRUE );
-
- g_rotate_dialog.z = spin;
- }
- }
- {
- auto vbox = create_dialog_vbox( 4 );
- hbox.pack_start( vbox, TRUE, TRUE, 0 );
- {
- auto button = create_dialog_button( "OK", G_CALLBACK( rotatedlg_ok ), &g_rotate_dialog );
- vbox.pack_start( button, FALSE, FALSE, 0 );
- widget_make_default( button );
- gtk_widget_add_accelerator( button , "clicked", accel, GDK_KEY_Return, (GdkModifierType)0, (GtkAccelFlags)0 );
- }
- {
- auto button = create_dialog_button( "Cancel", G_CALLBACK( rotatedlg_cancel ), &g_rotate_dialog );
- vbox.pack_start( button, FALSE, FALSE, 0 );
- gtk_widget_add_accelerator( button , "clicked", accel, GDK_KEY_Escape, (GdkModifierType)0, (GtkAccelFlags)0 );
- }
- {
- auto button = create_dialog_button( "Apply", G_CALLBACK( rotatedlg_apply ), &g_rotate_dialog );
- vbox.pack_start( button, FALSE, FALSE, 0 );
- }
- }
- }
- }
-
- g_rotate_dialog.window.show();
-}
-
-
-
-
-
-
-
-
-
-struct ScaleDialog
-{
- ui::Entry x{ui::null};
- ui::Entry y{ui::null};
- ui::Entry z{ui::null};
- ui::Window window{ui::null};
-};
-
-static gboolean scaledlg_apply( ui::Widget widget, ScaleDialog* scaleDialog ){
- float sx, sy, sz;
-
- sx = static_cast<float>( atof( gtk_entry_get_text( GTK_ENTRY( scaleDialog->x ) ) ) );
- sy = static_cast<float>( atof( gtk_entry_get_text( GTK_ENTRY( scaleDialog->y ) ) ) );
- sz = static_cast<float>( atof( gtk_entry_get_text( GTK_ENTRY( scaleDialog->z ) ) ) );
-
- StringOutputStream command;
- command << "scaleSelected -x " << sx << " -y " << sy << " -z " << sz;
- UndoableCommand undo( command.c_str() );
-
- Select_Scale( sx, sy, sz );
-
- return TRUE;
-}
-
-static gboolean scaledlg_cancel( ui::Widget widget, ScaleDialog* scaleDialog ){
- scaleDialog->window.hide();
-
- scaleDialog->x.text("1.0");
- scaleDialog->y.text("1.0");
- scaleDialog->z.text("1.0");
-
- return TRUE;
-}
-
-static gboolean scaledlg_ok( ui::Widget widget, ScaleDialog* scaleDialog ){
- scaledlg_apply( widget, scaleDialog );
- //scaledlg_cancel( widget, scaleDialog );
- scaleDialog->window.hide();
- return TRUE;
-}
-
-static gboolean scaledlg_delete( ui::Widget widget, GdkEventAny *event, ScaleDialog* scaleDialog ){
- scaledlg_cancel( widget, scaleDialog );
- return TRUE;
-}
-
-ScaleDialog g_scale_dialog;
-
-void DoScaleDlg(){
- if ( !g_scale_dialog.window ) {
- g_scale_dialog.window = MainFrame_getWindow().create_dialog_window("Arbitrary scale", G_CALLBACK(scaledlg_delete ), &g_scale_dialog );
-
- auto accel = ui::AccelGroup(ui::New);
- g_scale_dialog.window.add_accel_group( accel );
-
- {
- auto hbox = create_dialog_hbox( 4, 4 );
- g_scale_dialog.window.add(hbox);
- {
- auto table = create_dialog_table( 3, 2, 4, 4 );
- hbox.pack_start( table, TRUE, TRUE, 0 );
- {
- ui::Widget label = ui::Label( " X " );
- label.show();
- table.attach(label, {0, 1, 0, 1}, {0, 0});
- }
- {
- ui::Widget label = ui::Label( " Y " );
- label.show();
- table.attach(label, {0, 1, 1, 2}, {0, 0});
- }
- {
- ui::Widget label = ui::Label( " Z " );
- label.show();
- table.attach(label, {0, 1, 2, 3}, {0, 0});
- }
- {
- auto entry = ui::Entry(ui::New);
- entry.text("1.0");
- entry.show();
- table.attach(entry, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0});
-
- g_scale_dialog.x = entry;
- }
- {
- auto entry = ui::Entry(ui::New);
- entry.text("1.0");
- entry.show();
- table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0});
-
- g_scale_dialog.y = entry;
- }
- {
- auto entry = ui::Entry(ui::New);
- entry.text("1.0");
- entry.show();
- table.attach(entry, {1, 2, 2, 3}, {GTK_EXPAND | GTK_FILL, 0});
-
- g_scale_dialog.z = entry;
- }
- }
- {
- auto vbox = create_dialog_vbox( 4 );
- hbox.pack_start( vbox, TRUE, TRUE, 0 );
- {
- auto button = create_dialog_button( "OK", G_CALLBACK( scaledlg_ok ), &g_scale_dialog );
- vbox.pack_start( button, FALSE, FALSE, 0 );
- widget_make_default( button );
- gtk_widget_add_accelerator( button , "clicked", accel, GDK_KEY_Return, (GdkModifierType)0, (GtkAccelFlags)0 );
- }
- {
- auto button = create_dialog_button( "Cancel", G_CALLBACK( scaledlg_cancel ), &g_scale_dialog );
- vbox.pack_start( button, FALSE, FALSE, 0 );
- gtk_widget_add_accelerator( button , "clicked", accel, GDK_KEY_Escape, (GdkModifierType)0, (GtkAccelFlags)0 );
- }
- {
- auto button = create_dialog_button( "Apply", G_CALLBACK( scaledlg_apply ), &g_scale_dialog );
- vbox.pack_start( button, FALSE, FALSE, 0 );
- }
- }
- }
- }
-
- g_scale_dialog.window.show();
-}
+++ /dev/null
-/*
- Copyright (C) 2001-2006, William Joseph.
- All Rights Reserved.
-
- This file is part of GtkRadiant.
-
- GtkRadiant is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- GtkRadiant is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GtkRadiant; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "selection.h"
-#include "globaldefs.h"
-
-#include "debugging/debugging.h"
-
-#include <map>
-#include <list>
-#include <set>
-
-#include "windowobserver.h"
-#include "iundo.h"
-#include "ientity.h"
-#include "cullable.h"
-#include "renderable.h"
-#include "selectable.h"
-#include "editable.h"
-
-#include "math/frustum.h"
-#include "signal/signal.h"
-#include "generic/object.h"
-#include "selectionlib.h"
-#include "render.h"
-#include "view.h"
-#include "renderer.h"
-#include "stream/stringstream.h"
-#include "eclasslib.h"
-#include "generic/bitfield.h"
-#include "generic/static.h"
-#include "pivot.h"
-#include "stringio.h"
-#include "container/container.h"
-
-#include "grid.h"
-
-TextOutputStream& ostream_write( TextOutputStream& t, const Vector4& v ){
- return t << "[ " << v.x() << " " << v.y() << " " << v.z() << " " << v.w() << " ]";
-}
-
-TextOutputStream& ostream_write( TextOutputStream& t, const Matrix4& m ){
- return t << "[ " << m.x() << " " << m.y() << " " << m.z() << " " << m.t() << " ]";
-}
-
-struct Pivot2World
-{
- Matrix4 m_worldSpace;
- Matrix4 m_viewpointSpace;
- Matrix4 m_viewplaneSpace;
- Vector3 m_axis_screen;
-
- void update( const Matrix4& pivot2world, const Matrix4& modelview, const Matrix4& projection, const Matrix4& viewport ){
- Pivot2World_worldSpace( m_worldSpace, pivot2world, modelview, projection, viewport );
- Pivot2World_viewpointSpace( m_viewpointSpace, m_axis_screen, pivot2world, modelview, projection, viewport );
- Pivot2World_viewplaneSpace( m_viewplaneSpace, pivot2world, modelview, projection, viewport );
- }
-};
-
-
-void point_for_device_point( Vector3& point, const Matrix4& device2object, const float x, const float y, const float z ){
- // transform from normalised device coords to object coords
- point = vector4_projected( matrix4_transformed_vector4( device2object, Vector4( x, y, z, 1 ) ) );
-}
-
-void ray_for_device_point( Ray& ray, const Matrix4& device2object, const float x, const float y ){
- // point at x, y, zNear
- point_for_device_point( ray.origin, device2object, x, y, -1 );
-
- // point at x, y, zFar
- point_for_device_point( ray.direction, device2object, x, y, 1 );
-
- // construct ray
- vector3_subtract( ray.direction, ray.origin );
- vector3_normalise( ray.direction );
-}
-
-bool sphere_intersect_ray( const Vector3& origin, float radius, const Ray& ray, Vector3& intersection ){
- intersection = vector3_subtracted( origin, ray.origin );
- const double a = vector3_dot( intersection, ray.direction );
- const double d = radius * radius - ( vector3_dot( intersection, intersection ) - a * a );
-
- if ( d > 0 ) {
- intersection = vector3_added( ray.origin, vector3_scaled( ray.direction, a - sqrt( d ) ) );
- return true;
- }
- else
- {
- intersection = vector3_added( ray.origin, vector3_scaled( ray.direction, a ) );
- return false;
- }
-}
-
-void ray_intersect_ray( const Ray& ray, const Ray& other, Vector3& intersection ){
- intersection = vector3_subtracted( ray.origin, other.origin );
- //float a = 1;//vector3_dot(ray.direction, ray.direction); // always >= 0
- double dot = vector3_dot( ray.direction, other.direction );
- //float c = 1;//vector3_dot(other.direction, other.direction); // always >= 0
- double d = vector3_dot( ray.direction, intersection );
- double e = vector3_dot( other.direction, intersection );
- double D = 1 - dot * dot; //a*c - dot*dot; // always >= 0
-
- if ( D < 0.000001 ) {
- // the lines are almost parallel
- intersection = vector3_added( other.origin, vector3_scaled( other.direction, e ) );
- }
- else
- {
- intersection = vector3_added( other.origin, vector3_scaled( other.direction, ( e - dot * d ) / D ) );
- }
-}
-
-const Vector3 g_origin( 0, 0, 0 );
-const float g_radius = 64;
-
-void point_on_sphere( Vector3& point, const Matrix4& device2object, const float x, const float y ){
- Ray ray;
- ray_for_device_point( ray, device2object, x, y );
- sphere_intersect_ray( g_origin, g_radius, ray, point );
-}
-
-void point_on_axis( Vector3& point, const Vector3& axis, const Matrix4& device2object, const float x, const float y ){
- Ray ray;
- ray_for_device_point( ray, device2object, x, y );
- ray_intersect_ray( ray, Ray( Vector3( 0, 0, 0 ), axis ), point );
-}
-
-void point_on_plane( Vector3& point, const Matrix4& device2object, const float x, const float y ){
- Matrix4 object2device( matrix4_full_inverse( device2object ) );
- point = vector4_projected( matrix4_transformed_vector4( device2object, Vector4( x, y, object2device[14] / object2device[15], 1 ) ) );
-}
-
-//! a and b are unit vectors .. returns angle in radians
-inline float angle_between( const Vector3& a, const Vector3& b ){
- return static_cast<float>( 2.0 * atan2(
- vector3_length( vector3_subtracted( a, b ) ),
- vector3_length( vector3_added( a, b ) )
- ) );
-}
-
-
-#if GDEF_DEBUG
-class test_quat
-{
-public:
-test_quat( const Vector3& from, const Vector3& to ){
- Vector4 quaternion( quaternion_for_unit_vectors( from, to ) );
- Matrix4 matrix( matrix4_rotation_for_quaternion( quaternion_multiplied_by_quaternion( quaternion, c_quaternion_identity ) ) );
-}
-private:
-};
-
-static test_quat bleh( g_vector3_axis_x, g_vector3_axis_y );
-#endif
-
-//! axis is a unit vector
-inline void constrain_to_axis( Vector3& vec, const Vector3& axis ){
- vec = vector3_normalised( vector3_added( vec, vector3_scaled( axis, -vector3_dot( vec, axis ) ) ) );
-}
-
-//! a and b are unit vectors .. a and b must be orthogonal to axis .. returns angle in radians
-float angle_for_axis( const Vector3& a, const Vector3& b, const Vector3& axis ){
- if ( vector3_dot( axis, vector3_cross( a, b ) ) > 0.0 ) {
- return angle_between( a, b );
- }
- else{
- return -angle_between( a, b );
- }
-}
-
-float distance_for_axis( const Vector3& a, const Vector3& b, const Vector3& axis ){
- return static_cast<float>( vector3_dot( b, axis ) - vector3_dot( a, axis ) );
-}
-
-class Manipulatable
-{
-public:
-virtual void Construct( const Matrix4& device2manip, const float x, const float y ) = 0;
-virtual void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap ) = 0;
-};
-
-void transform_local2object( Matrix4& object, const Matrix4& local, const Matrix4& local2object ){
- object = matrix4_multiplied_by_matrix4(
- matrix4_multiplied_by_matrix4( local2object, local ),
- matrix4_full_inverse( local2object )
- );
-}
-
-class Rotatable
-{
-public:
-virtual ~Rotatable() = default;
-virtual void rotate( const Quaternion& rotation ) = 0;
-};
-
-class RotateFree : public Manipulatable
-{
-Vector3 m_start;
-Rotatable& m_rotatable;
-public:
-RotateFree( Rotatable& rotatable )
- : m_rotatable( rotatable ){
-}
-void Construct( const Matrix4& device2manip, const float x, const float y ){
- point_on_sphere( m_start, device2manip, x, y );
- vector3_normalise( m_start );
-}
-void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap ){
- Vector3 current;
- point_on_sphere( current, device2manip, x, y );
-
- if( snap ){
- Vector3 axis( 0, 0, 0 );
- for( std::size_t i = 0; i < 3; ++i ){
- if( current[i] == 0.0f ){
- axis[i] = 1.0f;
- break;
- }
- }
- if( vector3_length_squared( axis ) != 0 ){
- constrain_to_axis( current, axis );
- m_rotatable.rotate( quaternion_for_axisangle( axis, float_snapped( angle_for_axis( m_start, current, axis ), static_cast<float>( c_pi / 12.0 ) ) ) );
- return;
- }
- }
-
- vector3_normalise( current );
- m_rotatable.rotate( quaternion_for_unit_vectors( m_start, current ) );
-}
-};
-
-class RotateAxis : public Manipulatable
-{
-Vector3 m_axis;
-Vector3 m_start;
-Rotatable& m_rotatable;
-public:
-RotateAxis( Rotatable& rotatable )
- : m_rotatable( rotatable ){
-}
-void Construct( const Matrix4& device2manip, const float x, const float y ){
- point_on_sphere( m_start, device2manip, x, y );
- constrain_to_axis( m_start, m_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 ){
- Vector3 current;
- point_on_sphere( current, device2manip, x, y );
- constrain_to_axis( current, m_axis );
-
- if( snap ){
- m_rotatable.rotate( quaternion_for_axisangle( m_axis, float_snapped( angle_for_axis( m_start, current, m_axis ), static_cast<float>( c_pi / 12.0 ) ) ) );
- }
- else{
- m_rotatable.rotate( quaternion_for_axisangle( m_axis, angle_for_axis( m_start, current, m_axis ) ) );
- }
-}
-
-void SetAxis( const Vector3& axis ){
- m_axis = axis;
-}
-};
-
-void translation_local2object( Vector3& object, const Vector3& local, const Matrix4& local2object ){
- object = matrix4_get_translation_vec3(
- matrix4_multiplied_by_matrix4(
- matrix4_translated_by_vec3( local2object, local ),
- matrix4_full_inverse( local2object )
- )
- );
-}
-
-class Translatable
-{
-public:
-virtual ~Translatable() = default;
-virtual void translate( const Vector3& translation ) = 0;
-};
-
-class TranslateAxis : public Manipulatable
-{
-Vector3 m_start;
-Vector3 m_axis;
-Translatable& m_translatable;
-public:
-TranslateAxis( Translatable& translatable )
- : m_translatable( translatable ){
-}
-void Construct( const Matrix4& device2manip, const float x, const float y ){
- point_on_axis( m_start, m_axis, device2manip, x, y );
-}
-void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap ){
- Vector3 current;
- point_on_axis( current, m_axis, device2manip, x, y );
- current = vector3_scaled( m_axis, distance_for_axis( m_start, current, m_axis ) );
-
- translation_local2object( current, current, manip2object );
- vector3_snap( current, GetSnapGridSize() );
-
- m_translatable.translate( current );
-}
-
-void SetAxis( const Vector3& axis ){
- m_axis = axis;
-}
-};
-
-class TranslateFree : public Manipulatable
-{
-private:
-Vector3 m_start;
-Translatable& m_translatable;
-public:
-TranslateFree( Translatable& translatable )
- : m_translatable( translatable ){
-}
-void Construct( const Matrix4& device2manip, const float x, const float 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 ){
- Vector3 current;
- point_on_plane( current, device2manip, x, y );
- current = vector3_subtracted( current, m_start );
-
- if( snap ){
- for ( std::size_t i = 0; i < 3 ; ++i ){
- if( fabs( current[i] ) >= fabs( current[(i + 1) % 3] ) ){
- current[(i + 1) % 3] = 0.0f;
- }
- else{
- current[i] = 0.0f;
- }
- }
- }
-
- translation_local2object( current, current, manip2object );
- vector3_snap( current, GetSnapGridSize() );
-
- m_translatable.translate( current );
-}
-};
-
-void GetSelectionAABB( AABB& bounds );
-const Matrix4& SelectionSystem_GetPivot2World();
-
-class Scalable
-{
-public:
-virtual ~Scalable() = default;
-virtual void scale( const Vector3& scaling ) = 0;
-};
-
-
-class ScaleAxis : public Manipulatable
-{
-private:
-Vector3 m_start;
-Vector3 m_axis;
-Scalable& m_scalable;
-
-Vector3 m_choosen_extent;
-
-public:
-ScaleAxis( Scalable& scalable )
- : m_scalable( scalable ){
-}
-void Construct( const Matrix4& device2manip, const float x, const float y ){
- point_on_axis( m_start, m_axis, device2manip, x, y );
-
- AABB aabb;
- GetSelectionAABB( aabb );
- Vector3 transform_origin = vector4_to_vector3( SelectionSystem_GetPivot2World().t() );
- m_choosen_extent = Vector3(
- std::max( aabb.origin[0] + aabb.extents[0] - transform_origin[0], - aabb.origin[0] + aabb.extents[0] + transform_origin[0] ),
- std::max( aabb.origin[1] + aabb.extents[1] - transform_origin[1], - aabb.origin[1] + aabb.extents[1] + transform_origin[1] ),
- std::max( aabb.origin[2] + aabb.extents[2] - transform_origin[2], - aabb.origin[2] + aabb.extents[2] + transform_origin[2] )
- );
-
-}
-void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap ){
- //globalOutputStream() << "manip2object: " << manip2object << " device2manip: " << device2manip << " x: " << x << " y:" << y <<"\n";
- Vector3 current;
- point_on_axis( current, m_axis, device2manip, x, y );
- Vector3 delta = vector3_subtracted( current, m_start );
-
- translation_local2object( delta, delta, manip2object );
- vector3_snap( delta, GetSnapGridSize() );
-
- Vector3 start( vector3_snapped( m_start, GetSnapGridSize() != 0.0f ? GetSnapGridSize() : 0.001f ) );
- for ( std::size_t i = 0; i < 3 ; ++i ){ //prevent snapping to 0 with big gridsize
- if( float_snapped( m_start[i], 0.001f ) != 0.0f && start[i] == 0.0f ){
- start[i] = GetSnapGridSize();
- }
- }
- //globalOutputStream() << "m_start: " << m_start << " start: " << start << " delta: " << delta <<"\n";
- Vector3 scale(
- start[0] == 0 ? 1 : 1 + delta[0] / start[0],
- start[1] == 0 ? 1 : 1 + delta[1] / start[1],
- start[2] == 0 ? 1 : 1 + delta[2] / start[2]
- );
-
- for( std::size_t i = 0; i < 3; i++ ){
- if( m_choosen_extent[i] > 0.0625f ){ //epsilon to prevent super high scale for set of models, having really small extent, formed by origins
- scale[i] = ( m_choosen_extent[i] + delta[i] ) / m_choosen_extent[i];
- }
- }
- if( snap ){
- for( std::size_t i = 0; i < 3; i++ ){
- if( scale[i] == 1.0f ){
- scale[i] = vector3_dot( scale, m_axis );
- }
- }
- }
- //globalOutputStream() << "scale: " << scale <<"\n";
- m_scalable.scale( scale );
-}
-
-void SetAxis( const Vector3& axis ){
- m_axis = axis;
-}
-};
-
-class ScaleFree : public Manipulatable
-{
-private:
-Vector3 m_start;
-Scalable& m_scalable;
-
-Vector3 m_choosen_extent;
-
-public:
-ScaleFree( Scalable& scalable )
- : m_scalable( scalable ){
-}
-void Construct( const Matrix4& device2manip, const float x, const float y ){
- point_on_plane( m_start, device2manip, x, y );
-
- AABB aabb;
- GetSelectionAABB( aabb );
- Vector3 transform_origin = vector4_to_vector3( SelectionSystem_GetPivot2World().t() );
- m_choosen_extent = Vector3(
- std::max( aabb.origin[0] + aabb.extents[0] - transform_origin[0], - aabb.origin[0] + aabb.extents[0] + transform_origin[0] ),
- std::max( aabb.origin[1] + aabb.extents[1] - transform_origin[1], - aabb.origin[1] + aabb.extents[1] + transform_origin[1] ),
- std::max( aabb.origin[2] + aabb.extents[2] - transform_origin[2], - aabb.origin[2] + aabb.extents[2] + transform_origin[2] )
- );
-}
-void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap ){
- Vector3 current;
- point_on_plane( current, device2manip, x, y );
- Vector3 delta = vector3_subtracted( current, m_start );
-
- translation_local2object( delta, delta, manip2object );
- vector3_snap( delta, GetSnapGridSize() );
-
- Vector3 start( vector3_snapped( m_start, GetSnapGridSize() != 0.0f ? GetSnapGridSize() : 0.001f ) );
- for ( std::size_t i = 0; i < 3 ; ++i ){ //prevent snapping to 0 with big gridsize
- if( float_snapped( m_start[i], 0.001f ) != 0.0f && start[i] == 0.0f ){
- start[i] = GetSnapGridSize();
- }
- }
- Vector3 scale(
- start[0] == 0 ? 1 : 1 + delta[0] / start[0],
- start[1] == 0 ? 1 : 1 + delta[1] / start[1],
- start[2] == 0 ? 1 : 1 + delta[2] / start[2]
- );
-
- //globalOutputStream() << "m_start: " << m_start << " start: " << start << " delta: " << delta <<"\n";
- for( std::size_t i = 0; i < 3; i++ ){
- if( m_choosen_extent[i] > 0.0625f ){
- scale[i] = ( m_choosen_extent[i] + delta[i] ) / m_choosen_extent[i];
- }
- }
- //globalOutputStream() << "pre snap scale: " << scale <<"\n";
- if( snap ){
- float bestscale = scale[0];
- for( std::size_t i = 1; i < 3; i++ ){
- //if( fabs( 1.0f - fabs( scale[i] ) ) > fabs( 1.0f - fabs( bestscale ) ) ){
- if( fabs( scale[i] ) > fabs( bestscale ) && scale[i] != 1.0f ){ //harder to scale down with this, but glitchier with upper one
- bestscale = scale[i];
- }
- //globalOutputStream() << "bestscale: " << bestscale <<"\n";
- }
- for( std::size_t i = 0; i < 3; i++ ){
- if( start[i] != 0.0f ){ // !!!!check grid == 0 case
- scale[i] = ( scale[i] < 0.0f ) ? -fabs( bestscale ) : fabs( bestscale );
- }
- }
- }
- //globalOutputStream() << "scale: " << scale <<"\n";
- m_scalable.scale( scale );
-}
-};
-
-
-
-
-
-
-
-
-
-
-class RenderableClippedPrimitive : public OpenGLRenderable
-{
-struct primitive_t
-{
- PointVertex m_points[9];
- std::size_t m_count;
-};
-Matrix4 m_inverse;
-std::vector<primitive_t> m_primitives;
-public:
-Matrix4 m_world;
-
-void render( RenderStateFlags state ) const {
- for ( std::size_t i = 0; i < m_primitives.size(); ++i )
- {
- glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_primitives[i].m_points[0].colour );
- glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_primitives[i].m_points[0].vertex );
- switch ( m_primitives[i].m_count )
- {
- case 1: break;
- case 2: glDrawArrays( GL_LINES, 0, GLsizei( m_primitives[i].m_count ) ); break;
- default: glDrawArrays( GL_POLYGON, 0, GLsizei( m_primitives[i].m_count ) ); break;
- }
- }
-}
-
-void construct( const Matrix4& world2device ){
- m_inverse = matrix4_full_inverse( world2device );
- m_world = g_matrix4_identity;
-}
-
-void insert( const Vector4 clipped[9], std::size_t count ){
- add_one();
-
- m_primitives.back().m_count = count;
- for ( std::size_t i = 0; i < count; ++i )
- {
- Vector3 world_point( vector4_projected( matrix4_transformed_vector4( m_inverse, clipped[i] ) ) );
- m_primitives.back().m_points[i].vertex = vertex3f_for_vector3( world_point );
- }
-}
-
-void destroy(){
- m_primitives.clear();
-}
-private:
-void add_one(){
- m_primitives.push_back( primitive_t() );
-
- const Colour4b colour_clipped( 255, 127, 0, 255 );
-
- for ( std::size_t i = 0; i < 9; ++i )
- m_primitives.back().m_points[i].colour = colour_clipped;
-}
-};
-
-#if GDEF_DEBUG
-#define DEBUG_SELECTION
-#endif
-
-#if defined( DEBUG_SELECTION )
-Shader* g_state_clipped;
-RenderableClippedPrimitive g_render_clipped;
-#endif
-
-
-#if 0
-// dist_Point_to_Line(): get the distance of a point to a line.
-// Input: a Point P and a Line L (in any dimension)
-// Return: the shortest distance from P to L
-float
-dist_Point_to_Line( Point P, Line L ){
- Vector v = L.P1 - L.P0;
- Vector w = P - L.P0;
-
- double c1 = dot( w,v );
- double c2 = dot( v,v );
- double b = c1 / c2;
-
- Point Pb = L.P0 + b * v;
- return d( P, Pb );
-}
-#endif
-
-class Segment3D
-{
-typedef Vector3 point_type;
-public:
-Segment3D( const point_type& _p0, const point_type& _p1 )
- : p0( _p0 ), p1( _p1 ){
-}
-
-point_type p0, p1;
-};
-
-typedef Vector3 Point3D;
-
-inline double vector3_distance_squared( const Point3D& a, const Point3D& b ){
- return vector3_length_squared( b - a );
-}
-
-// get the distance of a point to a segment.
-Point3D segment_closest_point_to_point( const Segment3D& segment, const Point3D& point ){
- Vector3 v = segment.p1 - segment.p0;
- Vector3 w = point - segment.p0;
-
- double c1 = vector3_dot( w,v );
- if ( c1 <= 0 ) {
- return segment.p0;
- }
-
- double c2 = vector3_dot( v,v );
- if ( c2 <= c1 ) {
- return segment.p1;
- }
-
- return Point3D( segment.p0 + v * ( c1 / c2 ) );
-}
-
-double segment_dist_to_point_3d( const Segment3D& segment, const Point3D& point ){
- return vector3_distance_squared( point, segment_closest_point_to_point( segment, point ) );
-}
-
-typedef Vector3 point_t;
-typedef const Vector3* point_iterator_t;
-
-// crossing number test for a point in a polygon
-// This code is patterned after [Franklin, 2000]
-bool point_test_polygon_2d( const point_t& P, point_iterator_t start, point_iterator_t finish ){
- std::size_t crossings = 0;
-
- // loop through all edges of the polygon
- for ( point_iterator_t prev = finish - 1, cur = start; cur != finish; prev = cur, ++cur )
- { // edge from (*prev) to (*cur)
- if ( ( ( ( *prev )[1] <= P[1] ) && ( ( *cur )[1] > P[1] ) ) // an upward crossing
- || ( ( ( *prev )[1] > P[1] ) && ( ( *cur )[1] <= P[1] ) ) ) { // a downward crossing
- // compute the actual edge-ray intersect x-coordinate
- float vt = (float)( P[1] - ( *prev )[1] ) / ( ( *cur )[1] - ( *prev )[1] );
- if ( P[0] < ( *prev )[0] + vt * ( ( *cur )[0] - ( *prev )[0] ) ) { // P[0] < intersect
- ++crossings; // a valid crossing of y=P[1] right of P[0]
- }
- }
- }
- return ( crossings & 0x1 ) != 0; // 0 if even (out), and 1 if odd (in)
-}
-
-inline double triangle_signed_area_XY( const Vector3& p0, const Vector3& p1, const Vector3& p2 ){
- return ( ( p1[0] - p0[0] ) * ( p2[1] - p0[1] ) ) - ( ( p2[0] - p0[0] ) * ( p1[1] - p0[1] ) );
-}
-
-enum clipcull_t
-{
- eClipCullNone,
- eClipCullCW,
- eClipCullCCW,
-};
-
-
-inline SelectionIntersection select_point_from_clipped( Vector4& clipped ){
- return SelectionIntersection( clipped[2] / clipped[3], static_cast<float>( vector3_length_squared( Vector3( clipped[0] / clipped[3], clipped[1] / clipped[3], 0 ) ) ) );
-}
-
-void BestPoint( std::size_t count, Vector4 clipped[9], SelectionIntersection& best, clipcull_t cull ){
- Vector3 normalised[9];
-
- {
- for ( std::size_t i = 0; i < count; ++i )
- {
- normalised[i][0] = clipped[i][0] / clipped[i][3];
- normalised[i][1] = clipped[i][1] / clipped[i][3];
- normalised[i][2] = clipped[i][2] / clipped[i][3];
- }
- }
-
- if ( cull != eClipCullNone && count > 2 ) {
- double signed_area = triangle_signed_area_XY( normalised[0], normalised[1], normalised[2] );
-
- if ( ( cull == eClipCullCW && signed_area > 0 )
- || ( cull == eClipCullCCW && signed_area < 0 ) ) {
- return;
- }
- }
-
- if ( count == 2 ) {
- Segment3D segment( normalised[0], normalised[1] );
- Point3D point = segment_closest_point_to_point( segment, Vector3( 0, 0, 0 ) );
- assign_if_closer( best, SelectionIntersection( point.z(), 0 ) );
- }
- else if ( count > 2 && !point_test_polygon_2d( Vector3( 0, 0, 0 ), normalised, normalised + count ) ) {
- point_iterator_t end = normalised + count;
- for ( point_iterator_t previous = end - 1, current = normalised; current != end; previous = current, ++current )
- {
- Segment3D segment( *previous, *current );
- Point3D point = segment_closest_point_to_point( segment, Vector3( 0, 0, 0 ) );
- float depth = point.z();
- point.z() = 0;
- float distance = static_cast<float>( vector3_length_squared( point ) );
-
- assign_if_closer( best, SelectionIntersection( depth, distance ) );
- }
- }
- else if ( count > 2 ) {
- assign_if_closer(
- best,
- SelectionIntersection(
- static_cast<float>( ray_distance_to_plane(
- Ray( Vector3( 0, 0, 0 ), Vector3( 0, 0, 1 ) ),
- plane3_for_points( normalised[0], normalised[1], normalised[2] )
- ) ),
- 0
- )
- );
- }
-
-#if defined( DEBUG_SELECTION )
- if ( count >= 2 ) {
- g_render_clipped.insert( clipped, count );
- }
-#endif
-}
-
-void LineStrip_BestPoint( const Matrix4& local2view, const PointVertex* vertices, const std::size_t size, SelectionIntersection& best ){
- Vector4 clipped[2];
- for ( std::size_t i = 0; ( i + 1 ) < size; ++i )
- {
- const std::size_t count = matrix4_clip_line( local2view, vertex3f_to_vector3( vertices[i].vertex ), vertex3f_to_vector3( vertices[i + 1].vertex ), clipped );
- BestPoint( count, clipped, best, eClipCullNone );
- }
-}
-
-void LineLoop_BestPoint( const Matrix4& local2view, const PointVertex* vertices, const std::size_t size, SelectionIntersection& best ){
- Vector4 clipped[2];
- for ( std::size_t i = 0; i < size; ++i )
- {
- const std::size_t count = matrix4_clip_line( local2view, vertex3f_to_vector3( vertices[i].vertex ), vertex3f_to_vector3( vertices[( i + 1 ) % size].vertex ), clipped );
- BestPoint( count, clipped, best, eClipCullNone );
- }
-}
-
-void Line_BestPoint( const Matrix4& local2view, const PointVertex vertices[2], SelectionIntersection& best ){
- Vector4 clipped[2];
- const std::size_t count = matrix4_clip_line( local2view, vertex3f_to_vector3( vertices[0].vertex ), vertex3f_to_vector3( vertices[1].vertex ), clipped );
- BestPoint( count, clipped, best, eClipCullNone );
-}
-
-void Circle_BestPoint( const Matrix4& local2view, clipcull_t cull, const PointVertex* vertices, const std::size_t size, SelectionIntersection& best ){
- Vector4 clipped[9];
- for ( std::size_t i = 0; i < size; ++i )
- {
- const std::size_t count = matrix4_clip_triangle( local2view, g_vector3_identity, vertex3f_to_vector3( vertices[i].vertex ), vertex3f_to_vector3( vertices[( i + 1 ) % size].vertex ), clipped );
- BestPoint( count, clipped, best, cull );
- }
-}
-
-void Quad_BestPoint( const Matrix4& local2view, clipcull_t cull, const PointVertex* vertices, SelectionIntersection& best ){
- Vector4 clipped[9];
- {
- const std::size_t count = matrix4_clip_triangle( local2view, vertex3f_to_vector3( vertices[0].vertex ), vertex3f_to_vector3( vertices[1].vertex ), vertex3f_to_vector3( vertices[3].vertex ), clipped );
- BestPoint( count, clipped, best, cull );
- }
- {
- const std::size_t count = matrix4_clip_triangle( local2view, vertex3f_to_vector3( vertices[1].vertex ), vertex3f_to_vector3( vertices[2].vertex ), vertex3f_to_vector3( vertices[3].vertex ), clipped );
- BestPoint( count, clipped, best, cull );
- }
-}
-
-struct FlatShadedVertex
-{
- Vertex3f vertex;
- Colour4b colour;
- Normal3f normal;
-
- FlatShadedVertex(){
- }
-};
-
-
-typedef FlatShadedVertex* FlatShadedVertexIterator;
-void Triangles_BestPoint( const Matrix4& local2view, clipcull_t cull, FlatShadedVertexIterator first, FlatShadedVertexIterator last, SelectionIntersection& best ){
- for ( FlatShadedVertexIterator x( first ), y( first + 1 ), z( first + 2 ); x != last; x += 3, y += 3, z += 3 )
- {
- Vector4 clipped[9];
- BestPoint(
- matrix4_clip_triangle(
- local2view,
- reinterpret_cast<const Vector3&>( ( *x ).vertex ),
- reinterpret_cast<const Vector3&>( ( *y ).vertex ),
- reinterpret_cast<const Vector3&>( ( *z ).vertex ),
- clipped
- ),
- clipped,
- best,
- cull
- );
- }
-}
-
-
-typedef std::multimap<SelectionIntersection, Selectable*> SelectableSortedSet;
-
-class SelectionPool : public Selector
-{
-SelectableSortedSet m_pool;
-SelectionIntersection m_intersection;
-Selectable* m_selectable;
-
-public:
-void pushSelectable( Selectable& selectable ){
- m_intersection = SelectionIntersection();
- m_selectable = &selectable;
-}
-void popSelectable(){
- addSelectable( m_intersection, m_selectable );
- m_intersection = SelectionIntersection();
-}
-void addIntersection( const SelectionIntersection& intersection ){
- assign_if_closer( m_intersection, intersection );
-}
-void addSelectable( const SelectionIntersection& intersection, Selectable* selectable ){
- if ( intersection.valid() ) {
- m_pool.insert( SelectableSortedSet::value_type( intersection, selectable ) );
- }
-}
-
-typedef SelectableSortedSet::iterator iterator;
-
-iterator begin(){
- return m_pool.begin();
-}
-iterator end(){
- return m_pool.end();
-}
-
-bool failed(){
- return m_pool.empty();
-}
-};
-
-
-const Colour4b g_colour_sphere( 0, 0, 0, 255 );
-const Colour4b g_colour_screen( 0, 255, 255, 255 );
-const Colour4b g_colour_selected( 255, 255, 0, 255 );
-
-inline const Colour4b& colourSelected( const Colour4b& colour, bool selected ){
- return ( selected ) ? g_colour_selected : colour;
-}
-
-template<typename remap_policy>
-inline void draw_semicircle( const std::size_t segments, const float radius, PointVertex* vertices, remap_policy remap ){
- const double increment = c_pi / double(segments << 2);
-
- std::size_t count = 0;
- float x = radius;
- float y = 0;
- remap_policy::set( vertices[segments << 2].vertex, -radius, 0, 0 );
- while ( count < segments )
- {
- PointVertex* i = vertices + count;
- PointVertex* j = vertices + ( ( segments << 1 ) - ( count + 1 ) );
-
- PointVertex* k = i + ( segments << 1 );
- PointVertex* l = j + ( segments << 1 );
-
-#if 0
- PointVertex* m = i + ( segments << 2 );
- PointVertex* n = j + ( segments << 2 );
- PointVertex* o = k + ( segments << 2 );
- PointVertex* p = l + ( segments << 2 );
-#endif
-
- remap_policy::set( i->vertex, x,-y, 0 );
- remap_policy::set( k->vertex,-y,-x, 0 );
-#if 0
- remap_policy::set( m->vertex,-x, y, 0 );
- remap_policy::set( o->vertex, y, x, 0 );
-#endif
-
- ++count;
-
- {
- const double theta = increment * count;
- x = static_cast<float>( radius * cos( theta ) );
- y = static_cast<float>( radius * sin( theta ) );
- }
-
- remap_policy::set( j->vertex, y,-x, 0 );
- remap_policy::set( l->vertex,-x,-y, 0 );
-#if 0
- remap_policy::set( n->vertex,-y, x, 0 );
- remap_policy::set( p->vertex, x, y, 0 );
-#endif
- }
-}
-
-class Manipulator
-{
-public:
-virtual Manipulatable* GetManipulatable() = 0;
-virtual void testSelect( const View& view, const Matrix4& pivot2world ){
-}
-virtual void render( Renderer& renderer, const VolumeTest& volume, const Matrix4& pivot2world ){
-}
-virtual void setSelected( bool select ) = 0;
-virtual bool isSelected() const = 0;
-};
-
-
-inline Vector3 normalised_safe( const Vector3& self ){
- if ( vector3_equal( self, g_vector3_identity ) ) {
- return g_vector3_identity;
- }
- return vector3_normalised( self );
-}
-
-
-class RotateManipulator : public Manipulator
-{
-struct RenderableCircle : public OpenGLRenderable
-{
- Array<PointVertex> m_vertices;
-
- RenderableCircle( std::size_t size ) : m_vertices( size ){
- }
- void render( RenderStateFlags state ) const {
- glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_vertices.data()->colour );
- glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_vertices.data()->vertex );
- glDrawArrays( GL_LINE_LOOP, 0, GLsizei( m_vertices.size() ) );
- }
- void setColour( const Colour4b& colour ){
- for ( Array<PointVertex>::iterator i = m_vertices.begin(); i != m_vertices.end(); ++i )
- {
- ( *i ).colour = colour;
- }
- }
-};
-
-struct RenderableSemiCircle : public OpenGLRenderable
-{
- Array<PointVertex> m_vertices;
-
- RenderableSemiCircle( std::size_t size ) : m_vertices( size ){
- }
- void render( RenderStateFlags state ) const {
- glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_vertices.data()->colour );
- glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_vertices.data()->vertex );
- glDrawArrays( GL_LINE_STRIP, 0, GLsizei( m_vertices.size() ) );
- }
- void setColour( const Colour4b& colour ){
- for ( Array<PointVertex>::iterator i = m_vertices.begin(); i != m_vertices.end(); ++i )
- {
- ( *i ).colour = colour;
- }
- }
-};
-
-RotateFree m_free;
-RotateAxis m_axis;
-Vector3 m_axis_screen;
-RenderableSemiCircle m_circle_x;
-RenderableSemiCircle m_circle_y;
-RenderableSemiCircle m_circle_z;
-RenderableCircle m_circle_screen;
-RenderableCircle m_circle_sphere;
-SelectableBool m_selectable_x;
-SelectableBool m_selectable_y;
-SelectableBool m_selectable_z;
-SelectableBool m_selectable_screen;
-SelectableBool m_selectable_sphere;
-Pivot2World m_pivot;
-Matrix4 m_local2world_x;
-Matrix4 m_local2world_y;
-Matrix4 m_local2world_z;
-bool m_circle_x_visible;
-bool m_circle_y_visible;
-bool m_circle_z_visible;
-public:
-static Shader* m_state_outer;
-
-RotateManipulator( Rotatable& rotatable, std::size_t segments, float radius ) :
- m_free( rotatable ),
- m_axis( rotatable ),
- m_circle_x( ( segments << 2 ) + 1 ),
- m_circle_y( ( segments << 2 ) + 1 ),
- m_circle_z( ( segments << 2 ) + 1 ),
- m_circle_screen( segments << 3 ),
- m_circle_sphere( segments << 3 ){
- draw_semicircle( segments, radius, m_circle_x.m_vertices.data(), RemapYZX() );
- draw_semicircle( segments, radius, m_circle_y.m_vertices.data(), RemapZXY() );
- draw_semicircle( segments, radius, m_circle_z.m_vertices.data(), RemapXYZ() );
-
- draw_circle( segments, radius * 1.15f, m_circle_screen.m_vertices.data(), RemapXYZ() );
- draw_circle( segments, radius, m_circle_sphere.m_vertices.data(), RemapXYZ() );
-
- m_selectable_sphere.setSelected( true );
-}
-
-
-void UpdateColours(){
- m_circle_x.setColour( colourSelected( g_colour_x, m_selectable_x.isSelected() ) );
- m_circle_y.setColour( colourSelected( g_colour_y, m_selectable_y.isSelected() ) );
- m_circle_z.setColour( colourSelected( g_colour_z, m_selectable_z.isSelected() ) );
- m_circle_screen.setColour( colourSelected( g_colour_screen, m_selectable_screen.isSelected() ) );
- m_circle_sphere.setColour( colourSelected( g_colour_sphere, false ) );
-}
-
-void updateCircleTransforms(){
- Vector3 localViewpoint( matrix4_transformed_direction( matrix4_transposed( m_pivot.m_worldSpace ), vector4_to_vector3( m_pivot.m_viewpointSpace.z() ) ) );
-
- m_circle_x_visible = !vector3_equal_epsilon( g_vector3_axis_x, localViewpoint, 1e-6f );
- if ( m_circle_x_visible ) {
- m_local2world_x = g_matrix4_identity;
- vector4_to_vector3( m_local2world_x.y() ) = normalised_safe(
- vector3_cross( g_vector3_axis_x, localViewpoint )
- );
- vector4_to_vector3( m_local2world_x.z() ) = normalised_safe(
- vector3_cross( vector4_to_vector3( m_local2world_x.x() ), vector4_to_vector3( m_local2world_x.y() ) )
- );
- matrix4_premultiply_by_matrix4( m_local2world_x, m_pivot.m_worldSpace );
- }
-
- m_circle_y_visible = !vector3_equal_epsilon( g_vector3_axis_y, localViewpoint, 1e-6f );
- if ( m_circle_y_visible ) {
- m_local2world_y = g_matrix4_identity;
- vector4_to_vector3( m_local2world_y.z() ) = normalised_safe(
- vector3_cross( g_vector3_axis_y, localViewpoint )
- );
- vector4_to_vector3( m_local2world_y.x() ) = normalised_safe(
- vector3_cross( vector4_to_vector3( m_local2world_y.y() ), vector4_to_vector3( m_local2world_y.z() ) )
- );
- matrix4_premultiply_by_matrix4( m_local2world_y, m_pivot.m_worldSpace );
- }
-
- m_circle_z_visible = !vector3_equal_epsilon( g_vector3_axis_z, localViewpoint, 1e-6f );
- if ( m_circle_z_visible ) {
- m_local2world_z = g_matrix4_identity;
- vector4_to_vector3( m_local2world_z.x() ) = normalised_safe(
- vector3_cross( g_vector3_axis_z, localViewpoint )
- );
- vector4_to_vector3( m_local2world_z.y() ) = normalised_safe(
- vector3_cross( vector4_to_vector3( m_local2world_z.z() ), vector4_to_vector3( m_local2world_z.x() ) )
- );
- matrix4_premultiply_by_matrix4( m_local2world_z, m_pivot.m_worldSpace );
- }
-}
-
-void render( Renderer& renderer, const VolumeTest& volume, const Matrix4& pivot2world ){
- m_pivot.update( pivot2world, volume.GetModelview(), volume.GetProjection(), volume.GetViewport() );
- updateCircleTransforms();
-
- // temp hack
- UpdateColours();
-
- renderer.SetState( m_state_outer, Renderer::eWireframeOnly );
- renderer.SetState( m_state_outer, Renderer::eFullMaterials );
-
- renderer.addRenderable( m_circle_screen, m_pivot.m_viewpointSpace );
- renderer.addRenderable( m_circle_sphere, m_pivot.m_viewpointSpace );
-
- if ( m_circle_x_visible ) {
- renderer.addRenderable( m_circle_x, m_local2world_x );
- }
- if ( m_circle_y_visible ) {
- renderer.addRenderable( m_circle_y, m_local2world_y );
- }
- if ( m_circle_z_visible ) {
- renderer.addRenderable( m_circle_z, m_local2world_z );
- }
-}
-void testSelect( const View& view, const Matrix4& pivot2world ){
- m_pivot.update( pivot2world, view.GetModelview(), view.GetProjection(), view.GetViewport() );
- updateCircleTransforms();
-
- SelectionPool selector;
-
- {
- {
- Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_local2world_x ) );
-
-#if defined( DEBUG_SELECTION )
- g_render_clipped.construct( view.GetViewMatrix() );
-#endif
-
- SelectionIntersection best;
- LineStrip_BestPoint( local2view, m_circle_x.m_vertices.data(), m_circle_x.m_vertices.size(), best );
- selector.addSelectable( best, &m_selectable_x );
- }
-
- {
- Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_local2world_y ) );
-
-#if defined( DEBUG_SELECTION )
- g_render_clipped.construct( view.GetViewMatrix() );
-#endif
-
- SelectionIntersection best;
- LineStrip_BestPoint( local2view, m_circle_y.m_vertices.data(), m_circle_y.m_vertices.size(), best );
- selector.addSelectable( best, &m_selectable_y );
- }
-
- {
- Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_local2world_z ) );
-
-#if defined( DEBUG_SELECTION )
- g_render_clipped.construct( view.GetViewMatrix() );
-#endif
-
- SelectionIntersection best;
- LineStrip_BestPoint( local2view, m_circle_z.m_vertices.data(), m_circle_z.m_vertices.size(), best );
- selector.addSelectable( best, &m_selectable_z );
- }
- }
-
- {
- Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_pivot.m_viewpointSpace ) );
-
- {
- SelectionIntersection best;
- LineLoop_BestPoint( local2view, m_circle_screen.m_vertices.data(), m_circle_screen.m_vertices.size(), best );
- selector.addSelectable( best, &m_selectable_screen );
- }
-
- {
- SelectionIntersection best;
- Circle_BestPoint( local2view, eClipCullCW, m_circle_sphere.m_vertices.data(), m_circle_sphere.m_vertices.size(), best );
- selector.addSelectable( best, &m_selectable_sphere );
- }
- }
-
- m_axis_screen = m_pivot.m_axis_screen;
-
- if ( !selector.failed() ) {
- ( *selector.begin() ).second->setSelected( true );
- }
-}
-
-Manipulatable* GetManipulatable(){
- if ( m_selectable_x.isSelected() ) {
- m_axis.SetAxis( g_vector3_axis_x );
- return &m_axis;
- }
- else if ( m_selectable_y.isSelected() ) {
- m_axis.SetAxis( g_vector3_axis_y );
- return &m_axis;
- }
- else if ( m_selectable_z.isSelected() ) {
- m_axis.SetAxis( g_vector3_axis_z );
- return &m_axis;
- }
- else if ( m_selectable_screen.isSelected() ) {
- m_axis.SetAxis( m_axis_screen );
- return &m_axis;
- }
- else{
- return &m_free;
- }
-}
-
-void setSelected( bool select ){
- m_selectable_x.setSelected( select );
- m_selectable_y.setSelected( select );
- m_selectable_z.setSelected( select );
- m_selectable_screen.setSelected( select );
-}
-bool isSelected() const {
- return m_selectable_x.isSelected()
- | m_selectable_y.isSelected()
- | m_selectable_z.isSelected()
- | m_selectable_screen.isSelected()
- | m_selectable_sphere.isSelected();
-}
-};
-
-Shader* RotateManipulator::m_state_outer;
-
-
-const float arrowhead_length = 16;
-const float arrowhead_radius = 4;
-
-inline void draw_arrowline( const float length, PointVertex* line, const std::size_t axis ){
- ( *line++ ).vertex = vertex3f_identity;
- ( *line ).vertex = vertex3f_identity;
- vertex3f_to_array( ( *line ).vertex )[axis] = length - arrowhead_length;
-}
-
-template<typename VertexRemap, typename NormalRemap>
-inline void draw_arrowhead( const std::size_t segments, const float length, FlatShadedVertex* vertices, VertexRemap, NormalRemap ){
- std::size_t head_tris = ( segments << 3 );
- const double head_segment = c_2pi / head_tris;
- for ( std::size_t i = 0; i < head_tris; ++i )
- {
- {
- FlatShadedVertex& point = vertices[i * 6 + 0];
- VertexRemap::x( point.vertex ) = length - arrowhead_length;
- VertexRemap::y( point.vertex ) = arrowhead_radius * static_cast<float>( cos( i * head_segment ) );
- VertexRemap::z( point.vertex ) = arrowhead_radius * static_cast<float>( sin( i * head_segment ) );
- NormalRemap::x( point.normal ) = arrowhead_radius / arrowhead_length;
- NormalRemap::y( point.normal ) = static_cast<float>( cos( i * head_segment ) );
- NormalRemap::z( point.normal ) = static_cast<float>( sin( i * head_segment ) );
- }
- {
- FlatShadedVertex& point = vertices[i * 6 + 1];
- VertexRemap::x( point.vertex ) = length;
- VertexRemap::y( point.vertex ) = 0;
- VertexRemap::z( point.vertex ) = 0;
- NormalRemap::x( point.normal ) = arrowhead_radius / arrowhead_length;
- NormalRemap::y( point.normal ) = static_cast<float>( cos( ( i + 0.5 ) * head_segment ) );
- NormalRemap::z( point.normal ) = static_cast<float>( sin( ( i + 0.5 ) * head_segment ) );
- }
- {
- FlatShadedVertex& point = vertices[i * 6 + 2];
- VertexRemap::x( point.vertex ) = length - arrowhead_length;
- VertexRemap::y( point.vertex ) = arrowhead_radius * static_cast<float>( cos( ( i + 1 ) * head_segment ) );
- VertexRemap::z( point.vertex ) = arrowhead_radius * static_cast<float>( sin( ( i + 1 ) * head_segment ) );
- NormalRemap::x( point.normal ) = arrowhead_radius / arrowhead_length;
- NormalRemap::y( point.normal ) = static_cast<float>( cos( ( i + 1 ) * head_segment ) );
- NormalRemap::z( point.normal ) = static_cast<float>( sin( ( i + 1 ) * head_segment ) );
- }
-
- {
- FlatShadedVertex& point = vertices[i * 6 + 3];
- VertexRemap::x( point.vertex ) = length - arrowhead_length;
- VertexRemap::y( point.vertex ) = 0;
- VertexRemap::z( point.vertex ) = 0;
- NormalRemap::x( point.normal ) = -1;
- NormalRemap::y( point.normal ) = 0;
- NormalRemap::z( point.normal ) = 0;
- }
- {
- FlatShadedVertex& point = vertices[i * 6 + 4];
- VertexRemap::x( point.vertex ) = length - arrowhead_length;
- VertexRemap::y( point.vertex ) = arrowhead_radius * static_cast<float>( cos( i * head_segment ) );
- VertexRemap::z( point.vertex ) = arrowhead_radius * static_cast<float>( sin( i * head_segment ) );
- NormalRemap::x( point.normal ) = -1;
- NormalRemap::y( point.normal ) = 0;
- NormalRemap::z( point.normal ) = 0;
- }
- {
- FlatShadedVertex& point = vertices[i * 6 + 5];
- VertexRemap::x( point.vertex ) = length - arrowhead_length;
- VertexRemap::y( point.vertex ) = arrowhead_radius * static_cast<float>( cos( ( i + 1 ) * head_segment ) );
- VertexRemap::z( point.vertex ) = arrowhead_radius * static_cast<float>( sin( ( i + 1 ) * head_segment ) );
- NormalRemap::x( point.normal ) = -1;
- NormalRemap::y( point.normal ) = 0;
- NormalRemap::z( point.normal ) = 0;
- }
- }
-}
-
-template<typename Triple>
-class TripleRemapXYZ
-{
-public:
-static float& x( Triple& triple ){
- return triple.x();
-}
-static float& y( Triple& triple ){
- return triple.y();
-}
-static float& z( Triple& triple ){
- return triple.z();
-}
-};
-
-template<typename Triple>
-class TripleRemapYZX
-{
-public:
-static float& x( Triple& triple ){
- return triple.y();
-}
-static float& y( Triple& triple ){
- return triple.z();
-}
-static float& z( Triple& triple ){
- return triple.x();
-}
-};
-
-template<typename Triple>
-class TripleRemapZXY
-{
-public:
-static float& x( Triple& triple ){
- return triple.z();
-}
-static float& y( Triple& triple ){
- return triple.x();
-}
-static float& z( Triple& triple ){
- return triple.y();
-}
-};
-
-void vector3_print( const Vector3& v ){
- globalOutputStream() << "( " << v.x() << " " << v.y() << " " << v.z() << " )";
-}
-
-class TranslateManipulator : public Manipulator
-{
-struct RenderableArrowLine : public OpenGLRenderable
-{
- PointVertex m_line[2];
-
- RenderableArrowLine(){
- }
- void render( RenderStateFlags state ) const {
- glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_line[0].colour );
- glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_line[0].vertex );
- glDrawArrays( GL_LINES, 0, 2 );
- }
- void setColour( const Colour4b& colour ){
- m_line[0].colour = colour;
- m_line[1].colour = colour;
- }
-};
-struct RenderableArrowHead : public OpenGLRenderable
-{
- Array<FlatShadedVertex> m_vertices;
-
- RenderableArrowHead( std::size_t size )
- : m_vertices( size ){
- }
- void render( RenderStateFlags state ) const {
- glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( FlatShadedVertex ), &m_vertices.data()->colour );
- glVertexPointer( 3, GL_FLOAT, sizeof( FlatShadedVertex ), &m_vertices.data()->vertex );
- glNormalPointer( GL_FLOAT, sizeof( FlatShadedVertex ), &m_vertices.data()->normal );
- glDrawArrays( GL_TRIANGLES, 0, GLsizei( m_vertices.size() ) );
- }
- void setColour( const Colour4b& colour ){
- for ( Array<FlatShadedVertex>::iterator i = m_vertices.begin(); i != m_vertices.end(); ++i )
- {
- ( *i ).colour = colour;
- }
- }
-};
-struct RenderableQuad : public OpenGLRenderable
-{
- PointVertex m_quad[4];
- void render( RenderStateFlags state ) const {
- glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_quad[0].colour );
- glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_quad[0].vertex );
- glDrawArrays( GL_LINE_LOOP, 0, 4 );
- }
- void setColour( const Colour4b& colour ){
- m_quad[0].colour = colour;
- m_quad[1].colour = colour;
- m_quad[2].colour = colour;
- m_quad[3].colour = colour;
- }
-};
-
-TranslateFree m_free;
-TranslateAxis m_axis;
-RenderableArrowLine m_arrow_x;
-RenderableArrowLine m_arrow_y;
-RenderableArrowLine m_arrow_z;
-RenderableArrowHead m_arrow_head_x;
-RenderableArrowHead m_arrow_head_y;
-RenderableArrowHead m_arrow_head_z;
-RenderableQuad m_quad_screen;
-SelectableBool m_selectable_x;
-SelectableBool m_selectable_y;
-SelectableBool m_selectable_z;
-SelectableBool m_selectable_screen;
-Pivot2World m_pivot;
-public:
-static Shader* m_state_wire;
-static Shader* m_state_fill;
-
-TranslateManipulator( Translatable& translatable, std::size_t segments, float length ) :
- m_free( translatable ),
- 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 ) ){
- 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 );
- draw_arrowhead( segments, length, m_arrow_head_y.m_vertices.data(), TripleRemapYZX<Vertex3f>(), TripleRemapYZX<Normal3f>() );
- draw_arrowline( length, m_arrow_z.m_line, 2 );
- draw_arrowhead( segments, length, m_arrow_head_z.m_vertices.data(), TripleRemapZXY<Vertex3f>(), TripleRemapZXY<Normal3f>() );
-
- draw_quad( 16, m_quad_screen.m_quad );
-}
-
-void UpdateColours(){
- m_arrow_x.setColour( colourSelected( g_colour_x, m_selectable_x.isSelected() ) );
- m_arrow_head_x.setColour( colourSelected( g_colour_x, m_selectable_x.isSelected() ) );
- m_arrow_y.setColour( colourSelected( g_colour_y, m_selectable_y.isSelected() ) );
- m_arrow_head_y.setColour( colourSelected( g_colour_y, m_selectable_y.isSelected() ) );
- m_arrow_z.setColour( colourSelected( g_colour_z, m_selectable_z.isSelected() ) );
- m_arrow_head_z.setColour( colourSelected( g_colour_z, m_selectable_z.isSelected() ) );
- m_quad_screen.setColour( colourSelected( g_colour_screen, m_selectable_screen.isSelected() ) );
-}
-
-bool manipulator_show_axis( const Pivot2World& pivot, const Vector3& axis ){
- return fabs( vector3_dot( pivot.m_axis_screen, axis ) ) < 0.95;
-}
-
-void render( Renderer& renderer, const VolumeTest& volume, const Matrix4& pivot2world ){
- m_pivot.update( pivot2world, volume.GetModelview(), volume.GetProjection(), volume.GetViewport() );
-
- // temp hack
- UpdateColours();
-
- Vector3 x = vector3_normalised( vector4_to_vector3( m_pivot.m_worldSpace.x() ) );
- bool show_x = manipulator_show_axis( m_pivot, x );
-
- Vector3 y = vector3_normalised( vector4_to_vector3( m_pivot.m_worldSpace.y() ) );
- bool show_y = manipulator_show_axis( m_pivot, y );
-
- Vector3 z = vector3_normalised( vector4_to_vector3( m_pivot.m_worldSpace.z() ) );
- bool show_z = manipulator_show_axis( m_pivot, z );
-
- renderer.SetState( m_state_wire, Renderer::eWireframeOnly );
- renderer.SetState( m_state_wire, Renderer::eFullMaterials );
-
- if ( show_x ) {
- renderer.addRenderable( m_arrow_x, m_pivot.m_worldSpace );
- }
- if ( show_y ) {
- renderer.addRenderable( m_arrow_y, m_pivot.m_worldSpace );
- }
- if ( show_z ) {
- renderer.addRenderable( m_arrow_z, m_pivot.m_worldSpace );
- }
-
- renderer.addRenderable( m_quad_screen, m_pivot.m_viewplaneSpace );
-
- renderer.SetState( m_state_fill, Renderer::eWireframeOnly );
- renderer.SetState( m_state_fill, Renderer::eFullMaterials );
-
- if ( show_x ) {
- renderer.addRenderable( m_arrow_head_x, m_pivot.m_worldSpace );
- }
- if ( show_y ) {
- renderer.addRenderable( m_arrow_head_y, m_pivot.m_worldSpace );
- }
- if ( show_z ) {
- renderer.addRenderable( m_arrow_head_z, m_pivot.m_worldSpace );
- }
-}
-void testSelect( const View& view, const Matrix4& pivot2world ){
- m_pivot.update( pivot2world, view.GetModelview(), view.GetProjection(), view.GetViewport() );
-
- SelectionPool selector;
-
- Vector3 x = vector3_normalised( vector4_to_vector3( m_pivot.m_worldSpace.x() ) );
- bool show_x = manipulator_show_axis( m_pivot, x );
-
- Vector3 y = vector3_normalised( vector4_to_vector3( m_pivot.m_worldSpace.y() ) );
- bool show_y = manipulator_show_axis( m_pivot, y );
-
- Vector3 z = vector3_normalised( vector4_to_vector3( m_pivot.m_worldSpace.z() ) );
- bool show_z = manipulator_show_axis( m_pivot, z );
-
- {
- Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_pivot.m_viewpointSpace ) );
-
- {
- SelectionIntersection best;
- Quad_BestPoint( local2view, eClipCullCW, m_quad_screen.m_quad, best );
- if ( best.valid() ) {
- best = SelectionIntersection( 0, 0 );
- selector.addSelectable( best, &m_selectable_screen );
- }
- }
- }
-
- {
- Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_pivot.m_worldSpace ) );
-
-#if defined( DEBUG_SELECTION )
- g_render_clipped.construct( view.GetViewMatrix() );
-#endif
-
- if ( show_x ) {
- SelectionIntersection best;
- Line_BestPoint( local2view, m_arrow_x.m_line, best );
- Triangles_BestPoint( local2view, eClipCullCW, m_arrow_head_x.m_vertices.begin(), m_arrow_head_x.m_vertices.end(), best );
- selector.addSelectable( best, &m_selectable_x );
- }
-
- if ( show_y ) {
- SelectionIntersection best;
- Line_BestPoint( local2view, m_arrow_y.m_line, best );
- Triangles_BestPoint( local2view, eClipCullCW, m_arrow_head_y.m_vertices.begin(), m_arrow_head_y.m_vertices.end(), best );
- selector.addSelectable( best, &m_selectable_y );
- }
-
- if ( show_z ) {
- SelectionIntersection best;
- Line_BestPoint( local2view, m_arrow_z.m_line, best );
- Triangles_BestPoint( local2view, eClipCullCW, m_arrow_head_z.m_vertices.begin(), m_arrow_head_z.m_vertices.end(), best );
- selector.addSelectable( best, &m_selectable_z );
- }
- }
-
- if ( !selector.failed() ) {
- ( *selector.begin() ).second->setSelected( true );
- }
-}
-
-Manipulatable* GetManipulatable(){
- if ( m_selectable_x.isSelected() ) {
- m_axis.SetAxis( g_vector3_axis_x );
- return &m_axis;
- }
- else if ( m_selectable_y.isSelected() ) {
- m_axis.SetAxis( g_vector3_axis_y );
- return &m_axis;
- }
- else if ( m_selectable_z.isSelected() ) {
- m_axis.SetAxis( g_vector3_axis_z );
- return &m_axis;
- }
- else
- {
- return &m_free;
- }
-}
-
-void setSelected( bool select ){
- m_selectable_x.setSelected( select );
- m_selectable_y.setSelected( select );
- m_selectable_z.setSelected( select );
- m_selectable_screen.setSelected( select );
-}
-bool isSelected() const {
- return m_selectable_x.isSelected()
- | m_selectable_y.isSelected()
- | m_selectable_z.isSelected()
- | m_selectable_screen.isSelected();
-}
-};
-
-Shader* TranslateManipulator::m_state_wire;
-Shader* TranslateManipulator::m_state_fill;
-
-class ScaleManipulator : public Manipulator
-{
-struct RenderableArrow : public OpenGLRenderable
-{
- PointVertex m_line[2];
-
- void render( RenderStateFlags state ) const {
- glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_line[0].colour );
- glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_line[0].vertex );
- glDrawArrays( GL_LINES, 0, 2 );
- }
- void setColour( const Colour4b& colour ){
- m_line[0].colour = colour;
- m_line[1].colour = colour;
- }
-};
-struct RenderableQuad : public OpenGLRenderable
-{
- PointVertex m_quad[4];
- void render( RenderStateFlags state ) const {
- glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_quad[0].colour );
- glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_quad[0].vertex );
- glDrawArrays( GL_QUADS, 0, 4 );
- }
- void setColour( const Colour4b& colour ){
- m_quad[0].colour = colour;
- m_quad[1].colour = colour;
- m_quad[2].colour = colour;
- m_quad[3].colour = colour;
- }
-};
-
-ScaleFree m_free;
-ScaleAxis m_axis;
-RenderableArrow m_arrow_x;
-RenderableArrow m_arrow_y;
-RenderableArrow m_arrow_z;
-RenderableQuad m_quad_screen;
-SelectableBool m_selectable_x;
-SelectableBool m_selectable_y;
-SelectableBool m_selectable_z;
-SelectableBool m_selectable_screen;
-Pivot2World m_pivot;
-public:
-ScaleManipulator( Scalable& scalable, std::size_t segments, float length ) :
- m_free( scalable ),
- 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 );
-
- draw_quad( 16, m_quad_screen.m_quad );
-}
-
-Pivot2World& getPivot(){
- return m_pivot;
-}
-
-void UpdateColours(){
- m_arrow_x.setColour( colourSelected( g_colour_x, m_selectable_x.isSelected() ) );
- m_arrow_y.setColour( colourSelected( g_colour_y, m_selectable_y.isSelected() ) );
- m_arrow_z.setColour( colourSelected( g_colour_z, m_selectable_z.isSelected() ) );
- m_quad_screen.setColour( colourSelected( g_colour_screen, m_selectable_screen.isSelected() ) );
-}
-
-void render( Renderer& renderer, const VolumeTest& volume, const Matrix4& pivot2world ){
- m_pivot.update( pivot2world, volume.GetModelview(), volume.GetProjection(), volume.GetViewport() );
-
- // temp hack
- UpdateColours();
-
- renderer.addRenderable( m_arrow_x, m_pivot.m_worldSpace );
- renderer.addRenderable( m_arrow_y, m_pivot.m_worldSpace );
- renderer.addRenderable( m_arrow_z, m_pivot.m_worldSpace );
-
- renderer.addRenderable( m_quad_screen, m_pivot.m_viewpointSpace );
-}
-void testSelect( const View& view, const Matrix4& pivot2world ){
- m_pivot.update( pivot2world, view.GetModelview(), view.GetProjection(), view.GetViewport() );
-
- SelectionPool selector;
-
- {
- Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_pivot.m_worldSpace ) );
-
-#if defined( DEBUG_SELECTION )
- g_render_clipped.construct( view.GetViewMatrix() );
-#endif
-
- {
- SelectionIntersection best;
- Line_BestPoint( local2view, m_arrow_x.m_line, best );
- selector.addSelectable( best, &m_selectable_x );
- }
-
- {
- SelectionIntersection best;
- Line_BestPoint( local2view, m_arrow_y.m_line, best );
- selector.addSelectable( best, &m_selectable_y );
- }
-
- {
- SelectionIntersection best;
- Line_BestPoint( local2view, m_arrow_z.m_line, best );
- selector.addSelectable( best, &m_selectable_z );
- }
- }
-
- {
- Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_pivot.m_viewpointSpace ) );
-
- {
- SelectionIntersection best;
- Quad_BestPoint( local2view, eClipCullCW, m_quad_screen.m_quad, best );
- selector.addSelectable( best, &m_selectable_screen );
- }
- }
-
- if ( !selector.failed() ) {
- ( *selector.begin() ).second->setSelected( true );
- }
-}
-
-Manipulatable* GetManipulatable(){
- if ( m_selectable_x.isSelected() ) {
- m_axis.SetAxis( g_vector3_axis_x );
- return &m_axis;
- }
- else if ( m_selectable_y.isSelected() ) {
- m_axis.SetAxis( g_vector3_axis_y );
- return &m_axis;
- }
- else if ( m_selectable_z.isSelected() ) {
- m_axis.SetAxis( g_vector3_axis_z );
- return &m_axis;
- }
- else{
- return &m_free;
- }
-}
-
-void setSelected( bool select ){
- m_selectable_x.setSelected( select );
- m_selectable_y.setSelected( select );
- m_selectable_z.setSelected( select );
- m_selectable_screen.setSelected( select );
-}
-bool isSelected() const {
- return m_selectable_x.isSelected()
- | m_selectable_y.isSelected()
- | m_selectable_z.isSelected()
- | m_selectable_screen.isSelected();
-}
-};
-
-
-inline PlaneSelectable* Instance_getPlaneSelectable( scene::Instance& instance ){
- return InstanceTypeCast<PlaneSelectable>::cast( instance );
-}
-
-class PlaneSelectableSelectPlanes : public scene::Graph::Walker
-{
-Selector& m_selector;
-SelectionTest& m_test;
-PlaneCallback m_selectedPlaneCallback;
-public:
-PlaneSelectableSelectPlanes( Selector& selector, SelectionTest& test, const PlaneCallback& selectedPlaneCallback )
- : m_selector( selector ), m_test( test ), m_selectedPlaneCallback( selectedPlaneCallback ){
-}
-bool pre( const scene::Path& path, scene::Instance& instance ) const {
- if ( path.top().get().visible() ) {
- Selectable* selectable = Instance_getSelectable( instance );
- if ( selectable != 0 && selectable->isSelected() ) {
- PlaneSelectable* planeSelectable = Instance_getPlaneSelectable( instance );
- if ( planeSelectable != 0 ) {
- planeSelectable->selectPlanes( m_selector, m_test, m_selectedPlaneCallback );
- }
- }
- }
- return true;
-}
-};
-
-class PlaneSelectableSelectReversedPlanes : public scene::Graph::Walker
-{
-Selector& m_selector;
-const SelectedPlanes& m_selectedPlanes;
-public:
-PlaneSelectableSelectReversedPlanes( Selector& selector, const SelectedPlanes& selectedPlanes )
- : m_selector( selector ), m_selectedPlanes( selectedPlanes ){
-}
-bool pre( const scene::Path& path, scene::Instance& instance ) const {
- if ( path.top().get().visible() ) {
- Selectable* selectable = Instance_getSelectable( instance );
- if ( selectable != 0 && selectable->isSelected() ) {
- PlaneSelectable* planeSelectable = Instance_getPlaneSelectable( instance );
- if ( planeSelectable != 0 ) {
- planeSelectable->selectReversedPlanes( m_selector, m_selectedPlanes );
- }
- }
- }
- return true;
-}
-};
-
-void Scene_forEachPlaneSelectable_selectPlanes( scene::Graph& graph, Selector& selector, SelectionTest& test, const PlaneCallback& selectedPlaneCallback ){
- graph.traverse( PlaneSelectableSelectPlanes( selector, test, selectedPlaneCallback ) );
-}
-
-void Scene_forEachPlaneSelectable_selectReversedPlanes( scene::Graph& graph, Selector& selector, const SelectedPlanes& selectedPlanes ){
- graph.traverse( PlaneSelectableSelectReversedPlanes( selector, selectedPlanes ) );
-}
-
-
-class PlaneLess
-{
-public:
-bool operator()( const Plane3& plane, const Plane3& other ) const {
- if ( plane.a < other.a ) {
- return true;
- }
- if ( other.a < plane.a ) {
- return false;
- }
-
- if ( plane.b < other.b ) {
- return true;
- }
- if ( other.b < plane.b ) {
- return false;
- }
-
- if ( plane.c < other.c ) {
- return true;
- }
- if ( other.c < plane.c ) {
- return false;
- }
-
- if ( plane.d < other.d ) {
- return true;
- }
- if ( other.d < plane.d ) {
- return false;
- }
-
- return false;
-}
-};
-
-typedef std::set<Plane3, PlaneLess> PlaneSet;
-
-inline void PlaneSet_insert( PlaneSet& self, const Plane3& plane ){
- self.insert( plane );
-}
-
-inline bool PlaneSet_contains( const PlaneSet& self, const Plane3& plane ){
- return self.find( plane ) != self.end();
-}
-
-
-class SelectedPlaneSet : public SelectedPlanes
-{
-PlaneSet m_selectedPlanes;
-public:
-bool empty() const {
- return m_selectedPlanes.empty();
-}
-
-void insert( const Plane3& plane ){
- PlaneSet_insert( m_selectedPlanes, plane );
-}
-bool contains( const Plane3& plane ) const {
- return PlaneSet_contains( m_selectedPlanes, plane );
-}
-typedef MemberCaller<SelectedPlaneSet, void(const Plane3&), &SelectedPlaneSet::insert> InsertCaller;
-};
-
-
-bool Scene_forEachPlaneSelectable_selectPlanes( scene::Graph& graph, Selector& selector, SelectionTest& test ){
- SelectedPlaneSet selectedPlanes;
-
- Scene_forEachPlaneSelectable_selectPlanes( graph, selector, test, SelectedPlaneSet::InsertCaller( selectedPlanes ) );
- Scene_forEachPlaneSelectable_selectReversedPlanes( graph, selector, selectedPlanes );
-
- return !selectedPlanes.empty();
-}
-
-void Scene_Translate_Component_Selected( scene::Graph& graph, const Vector3& translation );
-void Scene_Translate_Selected( scene::Graph& graph, const Vector3& translation );
-void Scene_TestSelect_Primitive( Selector& selector, SelectionTest& test, const VolumeTest& volume );
-void Scene_TestSelect_Component( Selector& selector, SelectionTest& test, const VolumeTest& volume, SelectionSystem::EComponentMode componentMode );
-void Scene_TestSelect_Component_Selected( Selector& selector, SelectionTest& test, const VolumeTest& volume, SelectionSystem::EComponentMode componentMode );
-void Scene_SelectAll_Component( bool select, SelectionSystem::EComponentMode componentMode );
-
-class ResizeTranslatable : public Translatable
-{
-void translate( const Vector3& translation ){
- Scene_Translate_Component_Selected( GlobalSceneGraph(), translation );
-}
-};
-
-class DragTranslatable : public Translatable
-{
-void translate( const Vector3& translation ){
- if ( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent ) {
- Scene_Translate_Component_Selected( GlobalSceneGraph(), translation );
- }
- else
- {
- Scene_Translate_Selected( GlobalSceneGraph(), translation );
- }
-}
-};
-
-class SelectionVolume : public SelectionTest
-{
-Matrix4 m_local2view;
-const View& m_view;
-clipcull_t m_cull;
-Vector3 m_near;
-Vector3 m_far;
-public:
-SelectionVolume( const View& view )
- : m_view( view ){
-}
-
-const VolumeTest& getVolume() const {
- return m_view;
-}
-
-const Vector3& getNear() const {
- return m_near;
-}
-const Vector3& getFar() const {
- return m_far;
-}
-
-void BeginMesh( const Matrix4& localToWorld, bool twoSided ){
- m_local2view = matrix4_multiplied_by_matrix4( m_view.GetViewMatrix(), localToWorld );
-
- // Cull back-facing polygons based on winding being clockwise or counter-clockwise.
- // Don't cull if the view is wireframe and the polygons are two-sided.
- m_cull = twoSided && !m_view.fill() ? eClipCullNone : ( matrix4_handedness( localToWorld ) == MATRIX4_RIGHTHANDED ) ? eClipCullCW : eClipCullCCW;
-
- {
- Matrix4 screen2world( matrix4_full_inverse( m_local2view ) );
-
- m_near = vector4_projected(
- matrix4_transformed_vector4(
- screen2world,
- Vector4( 0, 0, -1, 1 )
- )
- );
-
- m_far = vector4_projected(
- matrix4_transformed_vector4(
- screen2world,
- Vector4( 0, 0, 1, 1 )
- )
- );
- }
-
-#if defined( DEBUG_SELECTION )
- g_render_clipped.construct( m_view.GetViewMatrix() );
-#endif
-}
-void TestPoint( const Vector3& point, SelectionIntersection& best ){
- Vector4 clipped;
- if ( matrix4_clip_point( m_local2view, point, clipped ) == c_CLIP_PASS ) {
- best = select_point_from_clipped( clipped );
- }
-}
-void TestPolygon( const VertexPointer& vertices, std::size_t count, SelectionIntersection& best ){
- Vector4 clipped[9];
- for ( std::size_t i = 0; i + 2 < count; ++i )
- {
- BestPoint(
- matrix4_clip_triangle(
- m_local2view,
- reinterpret_cast<const Vector3&>( vertices[0] ),
- reinterpret_cast<const Vector3&>( vertices[i + 1] ),
- reinterpret_cast<const Vector3&>( vertices[i + 2] ),
- clipped
- ),
- clipped,
- best,
- m_cull
- );
- }
-}
-void TestLineLoop( const VertexPointer& vertices, std::size_t count, SelectionIntersection& best ){
- if ( count == 0 ) {
- return;
- }
- Vector4 clipped[9];
- for ( VertexPointer::iterator i = vertices.begin(), end = i + count, prev = i + ( count - 1 ); i != end; prev = i, ++i )
- {
- BestPoint(
- matrix4_clip_line(
- m_local2view,
- reinterpret_cast<const Vector3&>( ( *prev ) ),
- reinterpret_cast<const Vector3&>( ( *i ) ),
- clipped
- ),
- clipped,
- best,
- m_cull
- );
- }
-}
-void TestLineStrip( const VertexPointer& vertices, std::size_t count, SelectionIntersection& best ){
- if ( count == 0 ) {
- return;
- }
- Vector4 clipped[9];
- for ( VertexPointer::iterator i = vertices.begin(), end = i + count, next = i + 1; next != end; i = next, ++next )
- {
- BestPoint(
- matrix4_clip_line(
- m_local2view,
- reinterpret_cast<const Vector3&>( ( *i ) ),
- reinterpret_cast<const Vector3&>( ( *next ) ),
- clipped
- ),
- clipped,
- best,
- m_cull
- );
- }
-}
-void TestLines( const VertexPointer& vertices, std::size_t count, SelectionIntersection& best ){
- if ( count == 0 ) {
- return;
- }
- Vector4 clipped[9];
- for ( VertexPointer::iterator i = vertices.begin(), end = i + count; i != end; i += 2 )
- {
- BestPoint(
- matrix4_clip_line(
- m_local2view,
- reinterpret_cast<const Vector3&>( ( *i ) ),
- reinterpret_cast<const Vector3&>( ( *( i + 1 ) ) ),
- clipped
- ),
- clipped,
- best,
- m_cull
- );
- }
-}
-void TestTriangles( const VertexPointer& vertices, const IndexPointer& indices, SelectionIntersection& best ){
- Vector4 clipped[9];
- for ( IndexPointer::iterator i( indices.begin() ); i != indices.end(); i += 3 )
- {
- BestPoint(
- matrix4_clip_triangle(
- m_local2view,
- reinterpret_cast<const Vector3&>( vertices[*i] ),
- reinterpret_cast<const Vector3&>( vertices[*( i + 1 )] ),
- reinterpret_cast<const Vector3&>( vertices[*( i + 2 )] ),
- clipped
- ),
- clipped,
- best,
- m_cull
- );
- }
-}
-void TestQuads( const VertexPointer& vertices, const IndexPointer& indices, SelectionIntersection& best ){
- Vector4 clipped[9];
- for ( IndexPointer::iterator i( indices.begin() ); i != indices.end(); i += 4 )
- {
- BestPoint(
- matrix4_clip_triangle(
- m_local2view,
- reinterpret_cast<const Vector3&>( vertices[*i] ),
- reinterpret_cast<const Vector3&>( vertices[*( i + 1 )] ),
- reinterpret_cast<const Vector3&>( vertices[*( i + 3 )] ),
- clipped
- ),
- clipped,
- best,
- m_cull
- );
- BestPoint(
- matrix4_clip_triangle(
- m_local2view,
- reinterpret_cast<const Vector3&>( vertices[*( i + 1 )] ),
- reinterpret_cast<const Vector3&>( vertices[*( i + 2 )] ),
- reinterpret_cast<const Vector3&>( vertices[*( i + 3 )] ),
- clipped
- ),
- clipped,
- best,
- m_cull
- );
- }
-}
-void TestQuadStrip( const VertexPointer& vertices, const IndexPointer& indices, SelectionIntersection& best ){
- Vector4 clipped[9];
- for ( IndexPointer::iterator i( indices.begin() ); i + 2 != indices.end(); i += 2 )
- {
- BestPoint(
- matrix4_clip_triangle(
- m_local2view,
- reinterpret_cast<const Vector3&>( vertices[*i] ),
- reinterpret_cast<const Vector3&>( vertices[*( i + 1 )] ),
- reinterpret_cast<const Vector3&>( vertices[*( i + 2 )] ),
- clipped
- ),
- clipped,
- best,
- m_cull
- );
- BestPoint(
- matrix4_clip_triangle(
- m_local2view,
- reinterpret_cast<const Vector3&>( vertices[*( i + 2 )] ),
- reinterpret_cast<const Vector3&>( vertices[*( i + 1 )] ),
- reinterpret_cast<const Vector3&>( vertices[*( i + 3 )] ),
- clipped
- ),
- clipped,
- best,
- m_cull
- );
- }
-}
-};
-
-class SelectionCounter
-{
-public:
-using func = void(const Selectable &);
-
-SelectionCounter( const SelectionChangeCallback& onchanged )
- : m_count( 0 ), m_onchanged( onchanged ){
-}
-void operator()( const Selectable& selectable ){
- if ( selectable.isSelected() ) {
- ++m_count;
- }
- else
- {
- ASSERT_MESSAGE( m_count != 0, "selection counter underflow" );
- --m_count;
- }
-
- m_onchanged( selectable );
-}
-bool empty() const {
- return m_count == 0;
-}
-std::size_t size() const {
- return m_count;
-}
-private:
-std::size_t m_count;
-SelectionChangeCallback m_onchanged;
-};
-
-inline void ConstructSelectionTest( View& view, const rect_t selection_box ){
- view.EnableScissor( selection_box.min[0], selection_box.max[0], selection_box.min[1], selection_box.max[1] );
-}
-
-inline const rect_t SelectionBoxForPoint( const float device_point[2], const float device_epsilon[2] ){
- rect_t selection_box;
- selection_box.min[0] = device_point[0] - device_epsilon[0];
- selection_box.min[1] = device_point[1] - device_epsilon[1];
- selection_box.max[0] = device_point[0] + device_epsilon[0];
- selection_box.max[1] = device_point[1] + device_epsilon[1];
- return selection_box;
-}
-
-inline const rect_t SelectionBoxForArea( const float device_point[2], const float device_delta[2] ){
- rect_t selection_box;
- selection_box.min[0] = ( device_delta[0] < 0 ) ? ( device_point[0] + device_delta[0] ) : ( device_point[0] );
- selection_box.min[1] = ( device_delta[1] < 0 ) ? ( device_point[1] + device_delta[1] ) : ( device_point[1] );
- selection_box.max[0] = ( device_delta[0] > 0 ) ? ( device_point[0] + device_delta[0] ) : ( device_point[0] );
- selection_box.max[1] = ( device_delta[1] > 0 ) ? ( device_point[1] + device_delta[1] ) : ( device_point[1] );
- return selection_box;
-}
-
-Quaternion construct_local_rotation( const Quaternion& world, const Quaternion& localToWorld ){
- return quaternion_normalised( quaternion_multiplied_by_quaternion(
- quaternion_normalised( quaternion_multiplied_by_quaternion(
- quaternion_inverse( localToWorld ),
- world
- ) ),
- localToWorld
- ) );
-}
-
-inline void matrix4_assign_rotation( Matrix4& matrix, const Matrix4& other ){
- matrix[0] = other[0];
- matrix[1] = other[1];
- matrix[2] = other[2];
- matrix[4] = other[4];
- matrix[5] = other[5];
- matrix[6] = other[6];
- matrix[8] = other[8];
- matrix[9] = other[9];
- matrix[10] = other[10];
-}
-
-void matrix4_assign_rotation_for_pivot( Matrix4& matrix, scene::Instance& instance ){
- Editable* editable = Node_getEditable( instance.path().top() );
- if ( editable != 0 ) {
- matrix4_assign_rotation( matrix, matrix4_multiplied_by_matrix4( instance.localToWorld(), editable->getLocalPivot() ) );
- }
- else
- {
- matrix4_assign_rotation( matrix, instance.localToWorld() );
- }
-}
-
-inline bool Instance_isSelectedComponents( scene::Instance& instance ){
- ComponentSelectionTestable* componentSelectionTestable = Instance_getComponentSelectionTestable( instance );
- return componentSelectionTestable != 0
- && componentSelectionTestable->isSelectedComponents();
-}
-
-class TranslateSelected : public SelectionSystem::Visitor
-{
-const Vector3& m_translate;
-public:
-TranslateSelected( const Vector3& translate )
- : m_translate( translate ){
-}
-void visit( scene::Instance& instance ) const {
- Transformable* transform = Instance_getTransformable( instance );
- if ( transform != 0 ) {
- transform->setType( TRANSFORM_PRIMITIVE );
- transform->setTranslation( m_translate );
- }
-}
-};
-
-void Scene_Translate_Selected( scene::Graph& graph, const Vector3& translation ){
- if ( GlobalSelectionSystem().countSelected() != 0 ) {
- GlobalSelectionSystem().foreachSelected( TranslateSelected( translation ) );
- }
-}
-
-Vector3 get_local_pivot( const Vector3& world_pivot, const Matrix4& localToWorld ){
- return Vector3(
- matrix4_transformed_point(
- matrix4_full_inverse( localToWorld ),
- world_pivot
- )
- );
-}
-
-void translation_for_pivoted_matrix_transform( Vector3& parent_translation, const Matrix4& local_transform, const Vector3& world_pivot, const Matrix4& localToWorld, const Matrix4& localToParent ){
- // we need a translation inside the parent system to move the origin of this object to the right place
-
- // mathematically, it must fulfill:
- //
- // local_translation local_transform local_pivot = local_pivot
- // local_translation = local_pivot - local_transform local_pivot
- //
- // or maybe?
- // local_transform local_translation local_pivot = local_pivot
- // local_translation local_pivot = local_transform^-1 local_pivot
- // local_translation + local_pivot = local_transform^-1 local_pivot
- // local_translation = local_transform^-1 local_pivot - local_pivot
-
- Vector3 local_pivot( get_local_pivot( world_pivot, localToWorld ) );
-
- Vector3 local_translation(
- vector3_subtracted(
- local_pivot,
- matrix4_transformed_point(
- local_transform,
- local_pivot
- )
- /*
- matrix4_transformed_point(
- matrix4_full_inverse(local_transform),
- local_pivot
- ),
- local_pivot
- */
- )
- );
-
- translation_local2object( parent_translation, local_translation, localToParent );
-
- /*
- // verify it!
- globalOutputStream() << "World pivot is at " << world_pivot << "\n";
- globalOutputStream() << "Local pivot is at " << local_pivot << "\n";
- globalOutputStream() << "Transformation " << local_transform << " moves it to: " << matrix4_transformed_point(local_transform, local_pivot) << "\n";
- globalOutputStream() << "Must move by " << local_translation << " in the local system" << "\n";
- globalOutputStream() << "Must move by " << parent_translation << " in the parent system" << "\n";
- */
-}
-
-void translation_for_pivoted_rotation( Vector3& parent_translation, const Quaternion& local_rotation, const Vector3& world_pivot, const Matrix4& localToWorld, const Matrix4& localToParent ){
- translation_for_pivoted_matrix_transform( parent_translation, matrix4_rotation_for_quaternion_quantised( local_rotation ), world_pivot, localToWorld, localToParent );
-}
-
-void translation_for_pivoted_scale( Vector3& parent_translation, const Vector3& world_scale, const Vector3& world_pivot, const Matrix4& localToWorld, const Matrix4& localToParent ){
- Matrix4 local_transform(
- matrix4_multiplied_by_matrix4(
- matrix4_full_inverse( localToWorld ),
- matrix4_multiplied_by_matrix4(
- matrix4_scale_for_vec3( world_scale ),
- localToWorld
- )
- )
- );
- local_transform.tx() = local_transform.ty() = local_transform.tz() = 0; // cancel translation parts
- translation_for_pivoted_matrix_transform( parent_translation, local_transform, world_pivot, localToWorld, localToParent );
-}
-
-class rotate_selected : public SelectionSystem::Visitor
-{
-const Quaternion& m_rotate;
-const Vector3& m_world_pivot;
-public:
-rotate_selected( const Quaternion& rotation, const Vector3& world_pivot )
- : m_rotate( rotation ), m_world_pivot( world_pivot ){
-}
-void visit( scene::Instance& instance ) const {
- TransformNode* transformNode = Node_getTransformNode( instance.path().top() );
- if ( transformNode != 0 ) {
- Transformable* transform = Instance_getTransformable( instance );
- if ( transform != 0 ) {
- transform->setType( TRANSFORM_PRIMITIVE );
- transform->setScale( c_scale_identity );
- transform->setTranslation( c_translation_identity );
-
- transform->setType( TRANSFORM_PRIMITIVE );
- transform->setRotation( m_rotate );
-
- {
- Editable* editable = Node_getEditable( instance.path().top() );
- const Matrix4& localPivot = editable != 0 ? editable->getLocalPivot() : g_matrix4_identity;
-
- Vector3 parent_translation;
- translation_for_pivoted_rotation(
- parent_translation,
- m_rotate,
- m_world_pivot,
- matrix4_multiplied_by_matrix4( instance.localToWorld(), localPivot ),
- matrix4_multiplied_by_matrix4( transformNode->localToParent(), localPivot )
- );
-
- transform->setTranslation( parent_translation );
- }
- }
- }
-}
-};
-
-void Scene_Rotate_Selected( scene::Graph& graph, const Quaternion& rotation, const Vector3& world_pivot ){
- if ( GlobalSelectionSystem().countSelected() != 0 ) {
- GlobalSelectionSystem().foreachSelected( rotate_selected( rotation, world_pivot ) );
- }
-}
-
-class scale_selected : public SelectionSystem::Visitor
-{
-const Vector3& m_scale;
-const Vector3& m_world_pivot;
-public:
-scale_selected( const Vector3& scaling, const Vector3& world_pivot )
- : m_scale( scaling ), m_world_pivot( world_pivot ){
-}
-void visit( scene::Instance& instance ) const {
- TransformNode* transformNode = Node_getTransformNode( instance.path().top() );
- if ( transformNode != 0 ) {
- Transformable* transform = Instance_getTransformable( instance );
- if ( transform != 0 ) {
- transform->setType( TRANSFORM_PRIMITIVE );
- transform->setScale( c_scale_identity );
- transform->setTranslation( c_translation_identity );
-
- transform->setType( TRANSFORM_PRIMITIVE );
- transform->setScale( m_scale );
- {
- Editable* editable = Node_getEditable( instance.path().top() );
- const Matrix4& localPivot = editable != 0 ? editable->getLocalPivot() : g_matrix4_identity;
-
- Vector3 parent_translation;
- translation_for_pivoted_scale(
- parent_translation,
- m_scale,
- m_world_pivot,
- matrix4_multiplied_by_matrix4( instance.localToWorld(), localPivot ),
- matrix4_multiplied_by_matrix4( transformNode->localToParent(), localPivot )
- );
-
- transform->setTranslation( parent_translation );
- }
- }
- }
-}
-};
-
-void Scene_Scale_Selected( scene::Graph& graph, const Vector3& scaling, const Vector3& world_pivot ){
- if ( GlobalSelectionSystem().countSelected() != 0 ) {
- GlobalSelectionSystem().foreachSelected( scale_selected( scaling, world_pivot ) );
- }
-}
-
-
-class translate_component_selected : public SelectionSystem::Visitor
-{
-const Vector3& m_translate;
-public:
-translate_component_selected( const Vector3& translate )
- : m_translate( translate ){
-}
-void visit( scene::Instance& instance ) const {
- Transformable* transform = Instance_getTransformable( instance );
- if ( transform != 0 ) {
- transform->setType( TRANSFORM_COMPONENT );
- transform->setTranslation( m_translate );
- }
-}
-};
-
-void Scene_Translate_Component_Selected( scene::Graph& graph, const Vector3& translation ){
- if ( GlobalSelectionSystem().countSelected() != 0 ) {
- GlobalSelectionSystem().foreachSelectedComponent( translate_component_selected( translation ) );
- }
-}
-
-class rotate_component_selected : public SelectionSystem::Visitor
-{
-const Quaternion& m_rotate;
-const Vector3& m_world_pivot;
-public:
-rotate_component_selected( const Quaternion& rotation, const Vector3& world_pivot )
- : m_rotate( rotation ), m_world_pivot( world_pivot ){
-}
-void visit( scene::Instance& instance ) const {
- Transformable* transform = Instance_getTransformable( instance );
- if ( transform != 0 ) {
- Vector3 parent_translation;
- translation_for_pivoted_rotation( parent_translation, m_rotate, m_world_pivot, instance.localToWorld(), Node_getTransformNode( instance.path().top() )->localToParent() );
-
- transform->setType( TRANSFORM_COMPONENT );
- transform->setRotation( m_rotate );
- transform->setTranslation( parent_translation );
- }
-}
-};
-
-void Scene_Rotate_Component_Selected( scene::Graph& graph, const Quaternion& rotation, const Vector3& world_pivot ){
- if ( GlobalSelectionSystem().countSelectedComponents() != 0 ) {
- GlobalSelectionSystem().foreachSelectedComponent( rotate_component_selected( rotation, world_pivot ) );
- }
-}
-
-class scale_component_selected : public SelectionSystem::Visitor
-{
-const Vector3& m_scale;
-const Vector3& m_world_pivot;
-public:
-scale_component_selected( const Vector3& scaling, const Vector3& world_pivot )
- : m_scale( scaling ), m_world_pivot( world_pivot ){
-}
-void visit( scene::Instance& instance ) const {
- Transformable* transform = Instance_getTransformable( instance );
- if ( transform != 0 ) {
- Vector3 parent_translation;
- translation_for_pivoted_scale( parent_translation, m_scale, m_world_pivot, instance.localToWorld(), Node_getTransformNode( instance.path().top() )->localToParent() );
-
- transform->setType( TRANSFORM_COMPONENT );
- transform->setScale( m_scale );
- transform->setTranslation( parent_translation );
- }
-}
-};
-
-void Scene_Scale_Component_Selected( scene::Graph& graph, const Vector3& scaling, const Vector3& world_pivot ){
- if ( GlobalSelectionSystem().countSelectedComponents() != 0 ) {
- GlobalSelectionSystem().foreachSelectedComponent( scale_component_selected( scaling, world_pivot ) );
- }
-}
-
-
-class BooleanSelector : public Selector
-{
-bool m_selected;
-SelectionIntersection m_intersection;
-Selectable* m_selectable;
-public:
-BooleanSelector() : m_selected( false ){
-}
-
-void pushSelectable( Selectable& selectable ){
- m_intersection = SelectionIntersection();
- m_selectable = &selectable;
-}
-void popSelectable(){
- if ( m_intersection.valid() ) {
- m_selected = true;
- }
- m_intersection = SelectionIntersection();
-}
-void addIntersection( const SelectionIntersection& intersection ){
- if ( m_selectable->isSelected() ) {
- assign_if_closer( m_intersection, intersection );
- }
-}
-
-bool isSelected(){
- return m_selected;
-}
-};
-
-class BestSelector : public Selector
-{
-SelectionIntersection m_intersection;
-Selectable* m_selectable;
-SelectionIntersection m_bestIntersection;
-std::list<Selectable*> m_bestSelectable;
-public:
-BestSelector() : m_bestIntersection( SelectionIntersection() ), m_bestSelectable( 0 ){
-}
-
-void pushSelectable( Selectable& selectable ){
- m_intersection = SelectionIntersection();
- m_selectable = &selectable;
-}
-void popSelectable(){
- if ( m_intersection.equalEpsilon( m_bestIntersection, 0.25f, 0.001f ) ) {
- m_bestSelectable.push_back( m_selectable );
- m_bestIntersection = m_intersection;
- }
- else if ( m_intersection < m_bestIntersection ) {
- m_bestSelectable.clear();
- m_bestSelectable.push_back( m_selectable );
- m_bestIntersection = m_intersection;
- }
- m_intersection = SelectionIntersection();
-}
-void addIntersection( const SelectionIntersection& intersection ){
- assign_if_closer( m_intersection, intersection );
-}
-
-std::list<Selectable*>& best(){
- return m_bestSelectable;
-}
-};
-
-class DragManipulator : public Manipulator
-{
-TranslateFree m_freeResize;
-TranslateFree m_freeDrag;
-ResizeTranslatable m_resize;
-DragTranslatable m_drag;
-SelectableBool m_dragSelectable;
-public:
-
-bool m_selected;
-
-DragManipulator() : m_freeResize( m_resize ), m_freeDrag( m_drag ), m_selected( false ){
-}
-
-Manipulatable* GetManipulatable(){
- return m_dragSelectable.isSelected() ? &m_freeDrag : &m_freeResize;
-}
-
-void testSelect( const View& view, const Matrix4& pivot2world ){
- SelectionPool selector;
-
- SelectionVolume test( view );
-
- if ( GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive ) {
- BooleanSelector booleanSelector;
-
- Scene_TestSelect_Primitive( booleanSelector, test, view );
-
- if ( booleanSelector.isSelected() ) {
- selector.addSelectable( SelectionIntersection( 0, 0 ), &m_dragSelectable );
- m_selected = false;
- }
- else
- {
- m_selected = Scene_forEachPlaneSelectable_selectPlanes( GlobalSceneGraph(), selector, test );
- }
- }
- else
- {
- BestSelector bestSelector;
- Scene_TestSelect_Component_Selected( bestSelector, test, view, GlobalSelectionSystem().ComponentMode() );
- for ( std::list<Selectable*>::iterator i = bestSelector.best().begin(); i != bestSelector.best().end(); ++i )
- {
- if ( !( *i )->isSelected() ) {
- GlobalSelectionSystem().setSelectedAllComponents( false );
- }
- m_selected = false;
- selector.addSelectable( SelectionIntersection( 0, 0 ), ( *i ) );
- m_dragSelectable.setSelected( true );
- }
- }
-
- for ( SelectionPool::iterator i = selector.begin(); i != selector.end(); ++i )
- {
- ( *i ).second->setSelected( true );
- }
-}
-
-void setSelected( bool select ){
- m_selected = select;
- m_dragSelectable.setSelected( select );
-}
-bool isSelected() const {
- return m_selected || m_dragSelectable.isSelected();
-}
-};
-
-class ClipManipulator : public Manipulator
-{
-public:
-
-Manipulatable* GetManipulatable(){
- ERROR_MESSAGE( "clipper is not manipulatable" );
- return 0;
-}
-
-void setSelected( bool select ){
-}
-bool isSelected() const {
- return false;
-}
-};
-
-class select_all : public scene::Graph::Walker
-{
-bool m_select;
-public:
-select_all( bool select )
- : m_select( select ){
-}
-bool pre( const scene::Path& path, scene::Instance& instance ) const {
- Selectable* selectable = Instance_getSelectable( instance );
- if ( selectable != 0 ) {
- selectable->setSelected( m_select );
- }
- return true;
-}
-};
-
-class select_all_component : public scene::Graph::Walker
-{
-bool m_select;
-SelectionSystem::EComponentMode m_mode;
-public:
-select_all_component( bool select, SelectionSystem::EComponentMode mode )
- : m_select( select ), m_mode( mode ){
-}
-bool pre( const scene::Path& path, scene::Instance& instance ) const {
- ComponentSelectionTestable* componentSelectionTestable = Instance_getComponentSelectionTestable( instance );
- if ( componentSelectionTestable ) {
- componentSelectionTestable->setSelectedComponents( m_select, m_mode );
- }
- return true;
-}
-};
-
-void Scene_SelectAll_Component( bool select, SelectionSystem::EComponentMode componentMode ){
- GlobalSceneGraph().traverse( select_all_component( select, componentMode ) );
-}
-
-
-// RadiantSelectionSystem
-class RadiantSelectionSystem :
- public SelectionSystem,
- public Translatable,
- public Rotatable,
- public Scalable,
- public Renderable
-{
-mutable Matrix4 m_pivot2world;
-Matrix4 m_pivot2world_start;
-Matrix4 m_manip2pivot_start;
-Translation m_translation;
-Rotation m_rotation;
-Scale m_scale;
-public:
-static Shader* m_state;
-bool m_bPreferPointEntsIn2D;
-private:
-EManipulatorMode m_manipulator_mode;
-Manipulator* m_manipulator;
-
-// state
-bool m_undo_begun;
-EMode m_mode;
-EComponentMode m_componentmode;
-
-SelectionCounter m_count_primitive;
-SelectionCounter m_count_component;
-
-TranslateManipulator m_translate_manipulator;
-RotateManipulator m_rotate_manipulator;
-ScaleManipulator m_scale_manipulator;
-DragManipulator m_drag_manipulator;
-ClipManipulator m_clip_manipulator;
-
-typedef SelectionList<scene::Instance> selection_t;
-selection_t m_selection;
-selection_t m_component_selection;
-
-Signal1<const Selectable&> m_selectionChanged_callbacks;
-
-void ConstructPivot() const;
-void setCustomPivotOrigin( Vector3& point ) const;
-public:
-void getSelectionAABB( AABB& bounds ) const;
-private:
-mutable bool m_pivotChanged;
-bool m_pivot_moving;
-mutable bool m_pivotIsCustom;
-
-void Scene_TestSelect( Selector& selector, SelectionTest& test, const View& view, SelectionSystem::EMode mode, SelectionSystem::EComponentMode componentMode );
-
-bool nothingSelected() const {
- return ( Mode() == eComponent && m_count_component.empty() )
- || ( Mode() == ePrimitive && m_count_primitive.empty() );
-}
-
-
-public:
-enum EModifier
-{
- eManipulator,
- eToggle,
- eReplace,
- eCycle,
- eSelect,
- eDeselect,
-};
-
-RadiantSelectionSystem() :
- m_bPreferPointEntsIn2D( true ),
- m_undo_begun( false ),
- m_mode( ePrimitive ),
- m_componentmode( eDefault ),
- m_count_primitive( SelectionChangedCaller( *this ) ),
- m_count_component( SelectionChangedCaller( *this ) ),
- m_translate_manipulator( *this, 2, 64 ),
- m_rotate_manipulator( *this, 8, 64 ),
- m_scale_manipulator( *this, 0, 64 ),
- m_pivotChanged( false ),
- m_pivot_moving( false ),
- m_pivotIsCustom( false ){
- SetManipulatorMode( eTranslate );
- pivotChanged();
- addSelectionChangeCallback( PivotChangedSelectionCaller( *this ) );
- AddGridChangeCallback( PivotChangedCaller( *this ) );
-}
-void pivotChanged() const {
- m_pivotChanged = true;
- SceneChangeNotify();
-}
-typedef ConstMemberCaller<RadiantSelectionSystem, void(), &RadiantSelectionSystem::pivotChanged> PivotChangedCaller;
-void pivotChangedSelection( const Selectable& selectable ){
- pivotChanged();
-}
-typedef MemberCaller<RadiantSelectionSystem, void(const Selectable&), &RadiantSelectionSystem::pivotChangedSelection> PivotChangedSelectionCaller;
-
-void SetMode( EMode mode ){
- if ( m_mode != mode ) {
- m_mode = mode;
- pivotChanged();
- }
-}
-EMode Mode() const {
- return m_mode;
-}
-void SetComponentMode( EComponentMode mode ){
- m_componentmode = mode;
-}
-EComponentMode ComponentMode() const {
- return m_componentmode;
-}
-void SetManipulatorMode( EManipulatorMode mode ){
- m_pivotIsCustom = false;
- m_manipulator_mode = mode;
- switch ( m_manipulator_mode )
- {
- case eTranslate: m_manipulator = &m_translate_manipulator; break;
- case eRotate: m_manipulator = &m_rotate_manipulator; break;
- case eScale: m_manipulator = &m_scale_manipulator; break;
- case eDrag: m_manipulator = &m_drag_manipulator; break;
- case eClip: m_manipulator = &m_clip_manipulator; break;
- }
- pivotChanged();
-}
-EManipulatorMode ManipulatorMode() const {
- return m_manipulator_mode;
-}
-
-SelectionChangeCallback getObserver( EMode mode ){
- if ( mode == ePrimitive ) {
- return makeCallback( m_count_primitive );
- }
- else
- {
- return makeCallback( m_count_component );
- }
-}
-std::size_t countSelected() const {
- return m_count_primitive.size();
-}
-std::size_t countSelectedComponents() const {
- return m_count_component.size();
-}
-void onSelectedChanged( scene::Instance& instance, const Selectable& selectable ){
- if ( selectable.isSelected() ) {
- m_selection.append( instance );
- }
- else
- {
- m_selection.erase( instance );
- }
-
- ASSERT_MESSAGE( m_selection.size() == m_count_primitive.size(), "selection-tracking error" );
-}
-void onComponentSelection( scene::Instance& instance, const Selectable& selectable ){
- if ( selectable.isSelected() ) {
- m_component_selection.append( instance );
- }
- else
- {
- m_component_selection.erase( instance );
- }
-
- ASSERT_MESSAGE( m_component_selection.size() == m_count_component.size(), "selection-tracking error" );
-}
-scene::Instance& ultimateSelected() const {
- ASSERT_MESSAGE( m_selection.size() > 0, "no instance selected" );
- return m_selection.back();
-}
-scene::Instance& penultimateSelected() const {
- ASSERT_MESSAGE( m_selection.size() > 1, "only one instance selected" );
- return *( *( --( --m_selection.end() ) ) );
-}
-void setSelectedAll( bool selected ){
- GlobalSceneGraph().traverse( select_all( selected ) );
-
- m_manipulator->setSelected( selected );
-}
-void setSelectedAllComponents( bool selected ){
- Scene_SelectAll_Component( selected, SelectionSystem::eVertex );
- Scene_SelectAll_Component( selected, SelectionSystem::eEdge );
- Scene_SelectAll_Component( selected, SelectionSystem::eFace );
-
- m_manipulator->setSelected( selected );
-}
-
-void foreachSelected( const Visitor& visitor ) const {
- selection_t::const_iterator i = m_selection.begin();
- while ( i != m_selection.end() )
- {
- visitor.visit( *( *( i++ ) ) );
- }
-}
-void foreachSelectedComponent( const Visitor& visitor ) const {
- selection_t::const_iterator i = m_component_selection.begin();
- while ( i != m_component_selection.end() )
- {
- visitor.visit( *( *( i++ ) ) );
- }
-}
-
-void addSelectionChangeCallback( const SelectionChangeHandler& handler ){
- m_selectionChanged_callbacks.connectLast( handler );
-}
-void selectionChanged( const Selectable& selectable ){
- m_selectionChanged_callbacks( selectable );
-}
-typedef MemberCaller<RadiantSelectionSystem, void(const Selectable&), &RadiantSelectionSystem::selectionChanged> SelectionChangedCaller;
-
-
-void startMove(){
- m_pivot2world_start = GetPivot2World();
-}
-
-bool SelectManipulator( const View& view, const float device_point[2], const float device_epsilon[2] ){
- if ( !nothingSelected() || ( ManipulatorMode() == eDrag && Mode() == eComponent ) ) {
-#if defined ( DEBUG_SELECTION )
- g_render_clipped.destroy();
-#endif
-
- m_manipulator->setSelected( false );
-
- if ( !nothingSelected() || ( ManipulatorMode() == eDrag && Mode() == eComponent ) ) {
- View scissored( view );
- ConstructSelectionTest( scissored, SelectionBoxForPoint( device_point, device_epsilon ) );
- m_manipulator->testSelect( scissored, GetPivot2World() );
- }
-
- startMove();
-
- m_pivot_moving = m_manipulator->isSelected();
-
- if ( m_pivot_moving ) {
- Pivot2World pivot;
- pivot.update( GetPivot2World(), view.GetModelview(), view.GetProjection(), view.GetViewport() );
-
- m_manip2pivot_start = matrix4_multiplied_by_matrix4( matrix4_full_inverse( m_pivot2world_start ), pivot.m_worldSpace );
-
- Matrix4 device2manip;
- ConstructDevice2Manip( device2manip, m_pivot2world_start, view.GetModelview(), view.GetProjection(), view.GetViewport() );
- m_manipulator->GetManipulatable()->Construct( device2manip, device_point[0], device_point[1] );
-
- m_undo_begun = false;
- }
-
- SceneChangeNotify();
- }
-
- return m_pivot_moving;
-}
-
-void deselectAll(){
- if ( Mode() == eComponent ) {
- setSelectedAllComponents( false );
- }
- else
- {
- setSelectedAll( false );
- }
-}
-
-void deselectComponentsOrAll( bool components ){
- if ( components ) {
- setSelectedAllComponents( false );
- }
- else
- {
- deselectAll();
- }
-}
-
-void SelectPoint( const View& view, const float device_point[2], const float device_epsilon[2], RadiantSelectionSystem::EModifier modifier, bool face ){
- //globalOutputStream() << device_point[0] << " " << device_point[1] << "\n";
- ASSERT_MESSAGE( fabs( device_point[0] ) <= 1.0f && fabs( device_point[1] ) <= 1.0f, "point-selection error" );
-
- if ( modifier == eReplace ) {
- deselectComponentsOrAll( face );
- }
-/*
-//nothingSelected() doesn't consider faces, selected in non-component mode, m
- if ( modifier == eCycle && nothingSelected() ){
- modifier = eReplace;
- }
-*/
- #if defined ( DEBUG_SELECTION )
- g_render_clipped.destroy();
- #endif
-
- {
- View scissored( view );
- ConstructSelectionTest( scissored, SelectionBoxForPoint( device_point, device_epsilon ) );
-
- SelectionVolume volume( scissored );
- SelectionPool selector;
- SelectionPool selector_point_ents;
- const bool prefer_point_ents = m_bPreferPointEntsIn2D && Mode() == ePrimitive && !view.fill() && !face
- && ( modifier == RadiantSelectionSystem::eReplace || modifier == RadiantSelectionSystem::eSelect || modifier == RadiantSelectionSystem::eDeselect );
-
- if( prefer_point_ents ){
- Scene_TestSelect( selector_point_ents, volume, scissored, eEntity, ComponentMode() );
- }
- if( prefer_point_ents && !selector_point_ents.failed() ){
- switch ( modifier )
- {
- // if cycle mode not enabled, enable it
- case RadiantSelectionSystem::eReplace:
- {
- // select closest
- ( *selector_point_ents.begin() ).second->setSelected( true );
- }
- break;
- case RadiantSelectionSystem::eSelect:
- {
- SelectionPool::iterator best = selector_point_ents.begin();
- if( !( *best ).second->isSelected() ){
- ( *best ).second->setSelected( true );
- }
- SelectionPool::iterator i = best;
- ++i;
- while ( i != selector_point_ents.end() )
- {
- if( ( *i ).first.equalEpsilon( ( *best ).first, 0.25f, 0.000001f ) ){
- if( !( *i ).second->isSelected() ){
- ( *i ).second->setSelected( true );
- }
- }
- else{
- break;
- }
- ++i;
- }
- }
- break;
- case RadiantSelectionSystem::eDeselect:
- {
- SelectionPool::iterator best = selector_point_ents.begin();
- if( ( *best ).second->isSelected() ){
- ( *best ).second->setSelected( false );
- }
- SelectionPool::iterator i = best;
- ++i;
- while ( i != selector_point_ents.end() )
- {
- if( ( *i ).first.equalEpsilon( ( *best ).first, 0.25f, 0.000001f ) ){
- if( ( *i ).second->isSelected() ){
- ( *i ).second->setSelected( false );
- }
- }
- else{
- break;
- }
- ++i;
- }
- }
- break;
- default:
- break;
- }
- }
- else{
- if ( face ){
- Scene_TestSelect_Component( selector, volume, scissored, eFace );
- }
- else{
- Scene_TestSelect( selector, volume, scissored, Mode(), ComponentMode() );
- }
-
- if ( !selector.failed() ) {
- switch ( modifier )
- {
- case RadiantSelectionSystem::eToggle:
- {
- SelectableSortedSet::iterator best = selector.begin();
- // toggle selection of the object with least depth
- if ( ( *best ).second->isSelected() ) {
- ( *best ).second->setSelected( false );
- }
- else{
- ( *best ).second->setSelected( true );
- }
- }
- break;
- // if cycle mode not enabled, enable it
- case RadiantSelectionSystem::eReplace:
- {
- // select closest
- ( *selector.begin() ).second->setSelected( true );
- }
- break;
- // select the next object in the list from the one already selected
- case RadiantSelectionSystem::eCycle:
- {
- bool CycleSelectionOccured = false;
- SelectionPool::iterator i = selector.begin();
- while ( i != selector.end() )
- {
- if ( ( *i ).second->isSelected() ) {
- deselectComponentsOrAll( face );
- ++i;
- if ( i != selector.end() ) {
- i->second->setSelected( true );
- }
- else
- {
- selector.begin()->second->setSelected( true );
- }
- CycleSelectionOccured = true;
- break;
- }
- ++i;
- }
- if( !CycleSelectionOccured ){
- deselectComponentsOrAll( face );
- ( *selector.begin() ).second->setSelected( true );
- }
- }
- break;
- case RadiantSelectionSystem::eSelect:
- {
- SelectionPool::iterator best = selector.begin();
- if( !( *best ).second->isSelected() ){
- ( *best ).second->setSelected( true );
- }
- SelectionPool::iterator i = best;
- ++i;
- while ( i != selector.end() )
- {
- if( ( *i ).first.equalEpsilon( ( *best ).first, 0.25f, 0.000001f ) ){
- if( !( *i ).second->isSelected() ){
- ( *i ).second->setSelected( true );
- }
- }
- else{
- break;
- }
- ++i;
- }
- }
- break;
- case RadiantSelectionSystem::eDeselect:
- {
- SelectionPool::iterator best = selector.begin();
- if( ( *best ).second->isSelected() ){
- ( *best ).second->setSelected( false );
- }
- SelectionPool::iterator i = best;
- ++i;
- while ( i != selector.end() )
- {
- if( ( *i ).first.equalEpsilon( ( *best ).first, 0.25f, 0.000001f ) ){
- if( ( *i ).second->isSelected() ){
- ( *i ).second->setSelected( false );
- }
- }
- else{
- break;
- }
- ++i;
- }
- }
- break;
- default:
- break;
- }
- }
- else if( modifier == eCycle ){
- deselectComponentsOrAll( face );
- }
- }
- }
-}
-
-bool SelectPoint_InitPaint( const View& view, const float device_point[2], const float device_epsilon[2], bool face ){
- ASSERT_MESSAGE( fabs( device_point[0] ) <= 1.0f && fabs( device_point[1] ) <= 1.0f, "point-selection error" );
- #if defined ( DEBUG_SELECTION )
- g_render_clipped.destroy();
- #endif
-
- {
- View scissored( view );
- ConstructSelectionTest( scissored, SelectionBoxForPoint( device_point, device_epsilon ) );
-
- SelectionVolume volume( scissored );
- SelectionPool selector;
- SelectionPool selector_point_ents;
- const bool prefer_point_ents = m_bPreferPointEntsIn2D && Mode() == ePrimitive && !view.fill() && !face;
-
- if( prefer_point_ents ){
- Scene_TestSelect( selector_point_ents, volume, scissored, eEntity, ComponentMode() );
- }
- if( prefer_point_ents && !selector_point_ents.failed() ){
- SelectableSortedSet::iterator best = selector_point_ents.begin();
- const bool wasSelected = ( *best ).second->isSelected();
- ( *best ).second->setSelected( !wasSelected );
- SelectableSortedSet::iterator i = best;
- ++i;
- while ( i != selector_point_ents.end() )
- {
- if( ( *i ).first.equalEpsilon( ( *best ).first, 0.25f, 0.000001f ) ){
- ( *i ).second->setSelected( !wasSelected );
- }
- else{
- break;
- }
- ++i;
- }
- return !wasSelected;
- }
- else{//do primitives, if ents failed
- if ( face ){
- Scene_TestSelect_Component( selector, volume, scissored, eFace );
- }
- else{
- Scene_TestSelect( selector, volume, scissored, Mode(), ComponentMode() );
- }
- if ( !selector.failed() ){
- SelectableSortedSet::iterator best = selector.begin();
- const bool wasSelected = ( *best ).second->isSelected();
- ( *best ).second->setSelected( !wasSelected );
- SelectableSortedSet::iterator i = best;
- ++i;
- while ( i != selector.end() )
- {
- if( ( *i ).first.equalEpsilon( ( *best ).first, 0.25f, 0.000001f ) ){
- ( *i ).second->setSelected( !wasSelected );
- }
- else{
- break;
- }
- ++i;
- }
- return !wasSelected;
- }
- else{
- return true;
- }
- }
- }
-}
-
-void SelectArea( const View& view, const float device_point[2], const float device_delta[2], RadiantSelectionSystem::EModifier modifier, bool face ){
- if ( modifier == eReplace ) {
- deselectComponentsOrAll( face );
- }
-
- #if defined ( DEBUG_SELECTION )
- g_render_clipped.destroy();
- #endif
-
- {
- View scissored( view );
- ConstructSelectionTest( scissored, SelectionBoxForArea( device_point, device_delta ) );
-
- SelectionVolume volume( scissored );
- SelectionPool pool;
- if ( face ) {
- Scene_TestSelect_Component( pool, volume, scissored, eFace );
- }
- else
- {
- Scene_TestSelect( pool, volume, scissored, Mode(), ComponentMode() );
- }
-
- for ( SelectionPool::iterator i = pool.begin(); i != pool.end(); ++i )
- {
- ( *i ).second->setSelected( !( modifier == RadiantSelectionSystem::eToggle && ( *i ).second->isSelected() ) );
- }
- }
-}
-
-
-void translate( const Vector3& translation ){
- if ( !nothingSelected() ) {
- //ASSERT_MESSAGE(!m_pivotChanged, "pivot is invalid");
-
- m_translation = translation;
-
- m_pivot2world = m_pivot2world_start;
- matrix4_translate_by_vec3( m_pivot2world, translation );
-
- if ( Mode() == eComponent ) {
- Scene_Translate_Component_Selected( GlobalSceneGraph(), m_translation );
- }
- else
- {
- Scene_Translate_Selected( GlobalSceneGraph(), m_translation );
- }
-
- SceneChangeNotify();
- }
-}
-void outputTranslation( TextOutputStream& ostream ){
- ostream << " -xyz " << m_translation.x() << " " << m_translation.y() << " " << m_translation.z();
-}
-void rotate( const Quaternion& rotation ){
- if ( !nothingSelected() ) {
- //ASSERT_MESSAGE(!m_pivotChanged, "pivot is invalid");
-
- m_rotation = rotation;
-
- if ( Mode() == eComponent ) {
- Scene_Rotate_Component_Selected( GlobalSceneGraph(), m_rotation, vector4_to_vector3( m_pivot2world.t() ) );
-
- matrix4_assign_rotation_for_pivot( m_pivot2world, m_component_selection.back() );
- }
- else
- {
- Scene_Rotate_Selected( GlobalSceneGraph(), m_rotation, vector4_to_vector3( m_pivot2world.t() ) );
-
- matrix4_assign_rotation_for_pivot( m_pivot2world, m_selection.back() );
- }
-
- SceneChangeNotify();
- }
-}
-void outputRotation( TextOutputStream& ostream ){
- ostream << " -eulerXYZ " << m_rotation.x() << " " << m_rotation.y() << " " << m_rotation.z();
-}
-void scale( const Vector3& scaling ){
- if ( !nothingSelected() ) {
- m_scale = scaling;
-
- if ( Mode() == eComponent ) {
- Scene_Scale_Component_Selected( GlobalSceneGraph(), m_scale, vector4_to_vector3( m_pivot2world.t() ) );
- }
- else
- {
- Scene_Scale_Selected( GlobalSceneGraph(), m_scale, vector4_to_vector3( m_pivot2world.t() ) );
- }
-
- SceneChangeNotify();
- }
-}
-void outputScale( TextOutputStream& ostream ){
- ostream << " -scale " << m_scale.x() << " " << m_scale.y() << " " << m_scale.z();
-}
-
-void rotateSelected( const Quaternion& rotation, bool snapOrigin ){
- if( snapOrigin && !m_pivotIsCustom ){
- m_pivot2world.tx() = float_snapped( m_pivot2world.tx(), GetSnapGridSize() );
- m_pivot2world.ty() = float_snapped( m_pivot2world.ty(), GetSnapGridSize() );
- m_pivot2world.tz() = float_snapped( m_pivot2world.tz(), GetSnapGridSize() );
- }
- startMove();
- rotate( rotation );
- freezeTransforms();
-}
-void translateSelected( const Vector3& translation ){
- startMove();
- translate( translation );
- freezeTransforms();
-}
-void scaleSelected( const Vector3& scaling ){
- startMove();
- scale( scaling );
- freezeTransforms();
-}
-
-void MoveSelected( const View& view, const float device_point[2], bool snap ){
- if ( m_manipulator->isSelected() ) {
- if ( !m_undo_begun ) {
- m_undo_begun = true;
- GlobalUndoSystem().start();
- }
-
- Matrix4 device2manip;
- 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 );
- }
-}
-
-/// \todo Support view-dependent nudge.
-void NudgeManipulator( const Vector3& nudge, const Vector3& view ){
- if ( ManipulatorMode() == eTranslate || ManipulatorMode() == eDrag ) {
- translateSelected( nudge );
- }
-}
-
-void endMove();
-void freezeTransforms();
-
-void renderSolid( Renderer& renderer, const VolumeTest& volume ) const;
-void renderWireframe( Renderer& renderer, const VolumeTest& volume ) const {
- renderSolid( renderer, volume );
-}
-
-const Matrix4& GetPivot2World() const {
- ConstructPivot();
- return m_pivot2world;
-}
-
-static void constructStatic(){
- m_state = GlobalShaderCache().capture( "$POINT" );
- #if defined( DEBUG_SELECTION )
- g_state_clipped = GlobalShaderCache().capture( "$DEBUG_CLIPPED" );
- #endif
- TranslateManipulator::m_state_wire = GlobalShaderCache().capture( "$WIRE_OVERLAY" );
- TranslateManipulator::m_state_fill = GlobalShaderCache().capture( "$FLATSHADE_OVERLAY" );
- RotateManipulator::m_state_outer = GlobalShaderCache().capture( "$WIRE_OVERLAY" );
-}
-
-static void destroyStatic(){
- #if defined( DEBUG_SELECTION )
- GlobalShaderCache().release( "$DEBUG_CLIPPED" );
- #endif
- GlobalShaderCache().release( "$WIRE_OVERLAY" );
- GlobalShaderCache().release( "$FLATSHADE_OVERLAY" );
- GlobalShaderCache().release( "$WIRE_OVERLAY" );
- GlobalShaderCache().release( "$POINT" );
-}
-};
-
-Shader* RadiantSelectionSystem::m_state = 0;
-
-
-namespace
-{
-RadiantSelectionSystem* g_RadiantSelectionSystem;
-
-inline RadiantSelectionSystem& getSelectionSystem(){
- return *g_RadiantSelectionSystem;
-}
-}
-
-#include "map.h"
-
-class testselect_entity_visible : public scene::Graph::Walker
-{
-Selector& m_selector;
-SelectionTest& m_test;
-public:
-testselect_entity_visible( Selector& selector, SelectionTest& test )
- : m_selector( selector ), m_test( test ){
-}
-bool pre( const scene::Path& path, scene::Instance& instance ) const {
- if( path.top().get_pointer() == Map_GetWorldspawn( g_map ) ||
- node_is_group( path.top().get() ) ){
- return false;
- }
- Selectable* selectable = Instance_getSelectable( instance );
- if ( selectable != 0
- && Node_isEntity( path.top() ) ) {
- m_selector.pushSelectable( *selectable );
- }
-
- SelectionTestable* selectionTestable = Instance_getSelectionTestable( instance );
- if ( selectionTestable ) {
- selectionTestable->testSelect( m_selector, m_test );
- }
-
- return true;
-}
-void post( const scene::Path& path, scene::Instance& instance ) const {
- Selectable* selectable = Instance_getSelectable( instance );
- if ( selectable != 0
- && Node_isEntity( path.top() ) ) {
- m_selector.popSelectable();
- }
-}
-};
-
-class testselect_primitive_visible : public scene::Graph::Walker
-{
-Selector& m_selector;
-SelectionTest& m_test;
-public:
-testselect_primitive_visible( Selector& selector, SelectionTest& test )
- : m_selector( selector ), m_test( test ){
-}
-bool pre( const scene::Path& path, scene::Instance& instance ) const {
- Selectable* selectable = Instance_getSelectable( instance );
- if ( selectable != 0 ) {
- m_selector.pushSelectable( *selectable );
- }
-
- SelectionTestable* selectionTestable = Instance_getSelectionTestable( instance );
- if ( selectionTestable ) {
- selectionTestable->testSelect( m_selector, m_test );
- }
-
- return true;
-}
-void post( const scene::Path& path, scene::Instance& instance ) const {
- Selectable* selectable = Instance_getSelectable( instance );
- if ( selectable != 0 ) {
- m_selector.popSelectable();
- }
-}
-};
-
-class testselect_component_visible : public scene::Graph::Walker
-{
-Selector& m_selector;
-SelectionTest& m_test;
-SelectionSystem::EComponentMode m_mode;
-public:
-testselect_component_visible( Selector& selector, SelectionTest& test, SelectionSystem::EComponentMode mode )
- : m_selector( selector ), m_test( test ), m_mode( mode ){
-}
-bool pre( const scene::Path& path, scene::Instance& instance ) const {
- ComponentSelectionTestable* componentSelectionTestable = Instance_getComponentSelectionTestable( instance );
- if ( componentSelectionTestable ) {
- componentSelectionTestable->testSelectComponents( m_selector, m_test, m_mode );
- }
-
- return true;
-}
-};
-
-
-class testselect_component_visible_selected : public scene::Graph::Walker
-{
-Selector& m_selector;
-SelectionTest& m_test;
-SelectionSystem::EComponentMode m_mode;
-public:
-testselect_component_visible_selected( Selector& selector, SelectionTest& test, SelectionSystem::EComponentMode mode )
- : m_selector( selector ), m_test( test ), m_mode( mode ){
-}
-bool pre( const scene::Path& path, scene::Instance& instance ) const {
- Selectable* selectable = Instance_getSelectable( instance );
- if ( selectable != 0 && selectable->isSelected() ) {
- ComponentSelectionTestable* componentSelectionTestable = Instance_getComponentSelectionTestable( instance );
- if ( componentSelectionTestable ) {
- componentSelectionTestable->testSelectComponents( m_selector, m_test, m_mode );
- }
- }
-
- return true;
-}
-};
-
-void Scene_TestSelect_Primitive( Selector& selector, SelectionTest& test, const VolumeTest& volume ){
- Scene_forEachVisible( GlobalSceneGraph(), volume, testselect_primitive_visible( selector, test ) );
-}
-
-void Scene_TestSelect_Component_Selected( Selector& selector, SelectionTest& test, const VolumeTest& volume, SelectionSystem::EComponentMode componentMode ){
- Scene_forEachVisible( GlobalSceneGraph(), volume, testselect_component_visible_selected( selector, test, componentMode ) );
-}
-
-void Scene_TestSelect_Component( Selector& selector, SelectionTest& test, const VolumeTest& volume, SelectionSystem::EComponentMode componentMode ){
- Scene_forEachVisible( GlobalSceneGraph(), volume, testselect_component_visible( selector, test, componentMode ) );
-}
-
-void RadiantSelectionSystem::Scene_TestSelect( Selector& selector, SelectionTest& test, const View& view, SelectionSystem::EMode mode, SelectionSystem::EComponentMode componentMode ){
- switch ( mode )
- {
- case eEntity:
- {
- Scene_forEachVisible( GlobalSceneGraph(), view, testselect_entity_visible( selector, test ) );
- }
- break;
- case ePrimitive:
- Scene_TestSelect_Primitive( selector, test, view );
- break;
- case eComponent:
- Scene_TestSelect_Component_Selected( selector, test, view, componentMode );
- break;
- }
-}
-
-class FreezeTransforms : public scene::Graph::Walker
-{
-public:
-bool pre( const scene::Path& path, scene::Instance& instance ) const {
- TransformNode* transformNode = Node_getTransformNode( path.top() );
- if ( transformNode != 0 ) {
- Transformable* transform = Instance_getTransformable( instance );
- if ( transform != 0 ) {
- transform->freezeTransform();
- }
- }
- return true;
-}
-};
-
-void RadiantSelectionSystem::freezeTransforms(){
- GlobalSceneGraph().traverse( FreezeTransforms() );
-}
-
-
-void RadiantSelectionSystem::endMove(){
- freezeTransforms();
-
- if ( Mode() == ePrimitive ) {
- if ( ManipulatorMode() == eDrag ) {
- Scene_SelectAll_Component( false, SelectionSystem::eFace );
- }
- }
-
- m_pivot_moving = false;
- pivotChanged();
-
- SceneChangeNotify();
-
- if ( m_undo_begun ) {
- StringOutputStream command;
-
- if ( ManipulatorMode() == eTranslate ) {
- command << "translateTool";
- outputTranslation( command );
- }
- else if ( ManipulatorMode() == eRotate ) {
- command << "rotateTool";
- outputRotation( command );
- }
- else if ( ManipulatorMode() == eScale ) {
- command << "scaleTool";
- outputScale( command );
- }
- else if ( ManipulatorMode() == eDrag ) {
- command << "dragTool";
- }
-
- GlobalUndoSystem().finish( command.c_str() );
- }
-
-}
-
-inline AABB Instance_getPivotBounds( scene::Instance& instance ){
- Entity* entity = Node_getEntity( instance.path().top() );
- if ( entity != 0
- && ( entity->getEntityClass().fixedsize
- || !node_is_group( instance.path().top() ) ) ) {
- Editable* editable = Node_getEditable( instance.path().top() );
- if ( editable != 0 ) {
- return AABB( vector4_to_vector3( matrix4_multiplied_by_matrix4( instance.localToWorld(), editable->getLocalPivot() ).t() ), Vector3( 0, 0, 0 ) );
- }
- else
- {
- return AABB( vector4_to_vector3( instance.localToWorld().t() ), Vector3( 0, 0, 0 ) );
- }
- }
-
- return instance.worldAABB();
-}
-
-class bounds_selected : public scene::Graph::Walker
-{
-AABB& m_bounds;
-public:
-bounds_selected( AABB& bounds )
- : m_bounds( bounds ){
- m_bounds = AABB();
-}
-bool pre( const scene::Path& path, scene::Instance& instance ) const {
- Selectable* selectable = Instance_getSelectable( instance );
- if ( selectable != 0
- && selectable->isSelected() ) {
- aabb_extend_by_aabb_safe( m_bounds, Instance_getPivotBounds( instance ) );
- }
- return true;
-}
-};
-
-class bounds_selected_component : public scene::Graph::Walker
-{
-AABB& m_bounds;
-public:
-bounds_selected_component( AABB& bounds )
- : m_bounds( bounds ){
- m_bounds = AABB();
-}
-bool pre( const scene::Path& path, scene::Instance& instance ) const {
- Selectable* selectable = Instance_getSelectable( instance );
- if ( selectable != 0
- && selectable->isSelected() ) {
- ComponentEditable* componentEditable = Instance_getComponentEditable( instance );
- if ( componentEditable ) {
- aabb_extend_by_aabb_safe( m_bounds, aabb_for_oriented_aabb_safe( componentEditable->getSelectedComponentsBounds(), instance.localToWorld() ) );
- }
- }
- return true;
-}
-};
-
-void Scene_BoundsSelected( scene::Graph& graph, AABB& bounds ){
- graph.traverse( bounds_selected( bounds ) );
-}
-
-void Scene_BoundsSelectedComponent( scene::Graph& graph, AABB& bounds ){
- graph.traverse( bounds_selected_component( bounds ) );
-}
-
-#if 0
-inline void pivot_for_node( Matrix4& pivot, scene::Node& node, scene::Instance& instance ){
- ComponentEditable* componentEditable = Instance_getComponentEditable( instance );
- if ( GlobalSelectionSystem().Mode() == SelectionSystem::eComponent
- && componentEditable != 0 ) {
- pivot = matrix4_translation_for_vec3( componentEditable->getSelectedComponentsBounds().origin );
- }
- else
- {
- Bounded* bounded = Instance_getBounded( instance );
- if ( bounded != 0 ) {
- pivot = matrix4_translation_for_vec3( bounded->localAABB().origin );
- }
- else
- {
- pivot = g_matrix4_identity;
- }
- }
-}
-#endif
-
-void RadiantSelectionSystem::ConstructPivot() const {
- if ( !m_pivotChanged || m_pivot_moving || m_pivotIsCustom ) {
- return;
- }
- m_pivotChanged = false;
-
- Vector3 m_object_pivot;
-
- if ( !nothingSelected() ) {
- {
- AABB bounds;
- if ( Mode() == eComponent ) {
- Scene_BoundsSelectedComponent( GlobalSceneGraph(), bounds );
- }
- else
- {
- Scene_BoundsSelected( GlobalSceneGraph(), bounds );
- }
- m_object_pivot = bounds.origin;
- }
-
- //vector3_snap( m_object_pivot, GetSnapGridSize() );
- //globalOutputStream() << m_object_pivot << "\n";
- m_pivot2world = matrix4_translation_for_vec3( m_object_pivot );
-
- switch ( m_manipulator_mode )
- {
- case eTranslate:
- break;
- case eRotate:
- if ( Mode() == eComponent ) {
- matrix4_assign_rotation_for_pivot( m_pivot2world, m_component_selection.back() );
- }
- else
- {
- matrix4_assign_rotation_for_pivot( m_pivot2world, m_selection.back() );
- }
- break;
- case eScale:
- if ( Mode() == eComponent ) {
- matrix4_assign_rotation_for_pivot( m_pivot2world, m_component_selection.back() );
- }
- else
- {
- matrix4_assign_rotation_for_pivot( m_pivot2world, m_selection.back() );
- }
- break;
- default:
- break;
- }
- }
-}
-
-void RadiantSelectionSystem::setCustomPivotOrigin( Vector3& point ) const {
- if ( !nothingSelected() && ( m_manipulator_mode == eTranslate || m_manipulator_mode == eRotate || m_manipulator_mode == eScale ) ) {
- AABB bounds;
- if ( Mode() == eComponent ) {
- Scene_BoundsSelectedComponent( GlobalSceneGraph(), bounds );
- }
- else
- {
- Scene_BoundsSelected( GlobalSceneGraph(), bounds );
- }
- //globalOutputStream() << point << "\n";
- for( std::size_t i = 0; i < 3; i++ ){
- if( point[i] < 900000.0f ){
- float bestsnapDist = fabs( bounds.origin[i] - point[i] );
- float bestsnapTo = bounds.origin[i];
- float othersnapDist = fabs( bounds.origin[i] + bounds.extents[i] - point[i] );
- if( othersnapDist < bestsnapDist ){
- bestsnapDist = othersnapDist;
- bestsnapTo = bounds.origin[i] + bounds.extents[i];
- }
- othersnapDist = fabs( bounds.origin[i] - bounds.extents[i] - point[i] );
- if( othersnapDist < bestsnapDist ){
- bestsnapDist = othersnapDist;
- bestsnapTo = bounds.origin[i] - bounds.extents[i];
- }
- othersnapDist = fabs( float_snapped( point[i], GetSnapGridSize() ) - point[i] );
- if( othersnapDist < bestsnapDist ){
- bestsnapDist = othersnapDist;
- bestsnapTo = float_snapped( point[i], GetSnapGridSize() );
- }
- point[i] = bestsnapTo;
-
- m_pivot2world[i + 12] = point[i]; //m_pivot2world.tx() .ty() .tz()
- }
- }
-
- switch ( m_manipulator_mode )
- {
- case eTranslate:
- break;
- case eRotate:
- if ( Mode() == eComponent ) {
- matrix4_assign_rotation_for_pivot( m_pivot2world, m_component_selection.back() );
- }
- else
- {
- matrix4_assign_rotation_for_pivot( m_pivot2world, m_selection.back() );
- }
- break;
- case eScale:
- if ( Mode() == eComponent ) {
- matrix4_assign_rotation_for_pivot( m_pivot2world, m_component_selection.back() );
- }
- else
- {
- matrix4_assign_rotation_for_pivot( m_pivot2world, m_selection.back() );
- }
- break;
- default:
- break;
- }
-
- m_pivotIsCustom = true;
- }
-}
-
-void RadiantSelectionSystem::getSelectionAABB( AABB& bounds ) const {
- if ( !nothingSelected() ) {
- if ( Mode() == eComponent ) {
- Scene_BoundsSelectedComponent( GlobalSceneGraph(), bounds );
- }
- else
- {
- Scene_BoundsSelected( GlobalSceneGraph(), bounds );
- }
- }
-}
-
-void GetSelectionAABB( AABB& bounds ){
- getSelectionSystem().getSelectionAABB( bounds );
-}
-
-const Matrix4& SelectionSystem_GetPivot2World(){
- return getSelectionSystem().GetPivot2World();
-}
-
-void RadiantSelectionSystem::renderSolid( Renderer& renderer, const VolumeTest& volume ) const {
- //if(view->TestPoint(m_object_pivot))
- if ( !nothingSelected() ) {
- renderer.Highlight( Renderer::ePrimitive, false );
- renderer.Highlight( Renderer::eFace, false );
-
- renderer.SetState( m_state, Renderer::eWireframeOnly );
- renderer.SetState( m_state, Renderer::eFullMaterials );
-
- m_manipulator->render( renderer, volume, GetPivot2World() );
- }
-
-#if defined( DEBUG_SELECTION )
- renderer.SetState( g_state_clipped, Renderer::eWireframeOnly );
- renderer.SetState( g_state_clipped, Renderer::eFullMaterials );
- renderer.addRenderable( g_render_clipped, g_render_clipped.m_world );
-#endif
-}
-
-#include "preferencesystem.h"
-#include "preferences.h"
-
-void SelectionSystem_constructPreferences( PreferencesPage& page ){
- page.appendCheckBox( "", "Prefer point entities in 2D", getSelectionSystem().m_bPreferPointEntsIn2D );
-}
-void SelectionSystem_constructPage( PreferenceGroup& group ){
- PreferencesPage page( group.createPage( "Selection", "Selection System Settings" ) );
- SelectionSystem_constructPreferences( page );
-}
-void SelectionSystem_registerPreferencesPage(){
- PreferencesDialog_addSettingsPage( FreeCaller<void(PreferenceGroup&), SelectionSystem_constructPage>() );
-}
-
-
-
-void SelectionSystem_OnBoundsChanged(){
- getSelectionSystem().pivotChanged();
-}
-
-SignalHandlerId SelectionSystem_boundsChanged;
-
-void SelectionSystem_Construct(){
- RadiantSelectionSystem::constructStatic();
-
- g_RadiantSelectionSystem = new RadiantSelectionSystem;
-
- SelectionSystem_boundsChanged = GlobalSceneGraph().addBoundsChangedCallback( FreeCaller<void(), SelectionSystem_OnBoundsChanged>() );
-
- GlobalShaderCache().attachRenderable( getSelectionSystem() );
-
- GlobalPreferenceSystem().registerPreference( "PreferPointEntsIn2D", make_property_string( getSelectionSystem().m_bPreferPointEntsIn2D ) );
- SelectionSystem_registerPreferencesPage();
-}
-
-void SelectionSystem_Destroy(){
- GlobalShaderCache().detachRenderable( getSelectionSystem() );
-
- GlobalSceneGraph().removeBoundsChangedCallback( SelectionSystem_boundsChanged );
-
- delete g_RadiantSelectionSystem;
-
- RadiantSelectionSystem::destroyStatic();
-}
-
-
-
-
-inline float screen_normalised( float pos, std::size_t size ){
- return ( ( 2.0f * pos ) / size ) - 1.0f;
-}
-
-typedef Vector2 DeviceVector;
-
-inline DeviceVector window_to_normalised_device( WindowVector window, std::size_t width, std::size_t height ){
- return DeviceVector( screen_normalised( window.x(), width ), screen_normalised( height - 1 - window.y(), height ) );
-}
-
-inline float device_constrained( float pos ){
- return std::min( 1.0f, std::max( -1.0f, pos ) );
-}
-
-inline DeviceVector device_constrained( DeviceVector device ){
- return DeviceVector( device_constrained( device.x() ), device_constrained( device.y() ) );
-}
-
-inline float window_constrained( float pos, std::size_t origin, std::size_t size ){
- return std::min( static_cast<float>( origin + size ), std::max( static_cast<float>( origin ), pos ) );
-}
-
-inline WindowVector window_constrained( WindowVector window, std::size_t x, std::size_t y, std::size_t width, std::size_t height ){
- return WindowVector( window_constrained( window.x(), x, width ), window_constrained( window.y(), y, height ) );
-}
-
-typedef Callback<void(DeviceVector)> MouseEventCallback;
-
-Single<MouseEventCallback> g_mouseMovedCallback;
-Single<MouseEventCallback> g_mouseUpCallback;
-
-#if 1
-const ButtonIdentifier c_button_select = c_buttonLeft;
-const ButtonIdentifier c_button_select2 = c_buttonRight;
-const ModifierFlags c_modifier_manipulator = c_modifierNone;
-const ModifierFlags c_modifier_toggle = c_modifierShift;
-const ModifierFlags c_modifier_replace = c_modifierShift | c_modifierAlt;
-const ModifierFlags c_modifier_face = c_modifierControl;
-#else
-const ButtonIdentifier c_button_select = c_buttonLeft;
-const ModifierFlags c_modifier_manipulator = c_modifierNone;
-const ModifierFlags c_modifier_toggle = c_modifierControl;
-const ModifierFlags c_modifier_replace = c_modifierNone;
-const ModifierFlags c_modifier_face = c_modifierShift;
-#endif
-const ModifierFlags c_modifier_toggle_face = c_modifier_toggle | c_modifier_face;
-const ModifierFlags c_modifier_replace_face = c_modifier_replace | c_modifier_face;
-
-const ButtonIdentifier c_button_texture = c_buttonMiddle;
-const ModifierFlags c_modifier_apply_texture1 = c_modifierControl | c_modifierShift;
-const ModifierFlags c_modifier_apply_texture2 = c_modifierControl;
-const ModifierFlags c_modifier_apply_texture3 = c_modifierShift;
-const ModifierFlags c_modifier_copy_texture = c_modifierNone;
-
-class Selector_
-{
-RadiantSelectionSystem::EModifier modifier_for_state( ModifierFlags state ){
- if ( ( state == c_modifier_toggle || state == c_modifier_toggle_face || state == c_modifier_face ) ) {
- if( m_mouse2 ){
- return RadiantSelectionSystem::eReplace;
- }
- else{
- return RadiantSelectionSystem::eToggle;
- }
- }
- return RadiantSelectionSystem::eManipulator;
-}
-
-rect_t getDeviceArea() const {
- DeviceVector delta( m_current - m_start );
- if ( selecting() && fabs( delta.x() ) > m_epsilon.x() && fabs( delta.y() ) > m_epsilon.y() ) {
- return SelectionBoxForArea( &m_start[0], &delta[0] );
- }
- else
- {
- rect_t default_area = { { 0, 0, }, { 0, 0, }, };
- return default_area;
- }
-}
-
-public:
-DeviceVector m_start;
-DeviceVector m_current;
-DeviceVector m_epsilon;
-ModifierFlags m_state;
-bool m_mouse2;
-bool m_mouseMoved;
-bool m_mouseMovedWhilePressed;
-bool m_paintSelect;
-const View* m_view;
-RectangleCallback m_window_update;
-
-Selector_() : m_start( 0.0f, 0.0f ), m_current( 0.0f, 0.0f ), m_state( c_modifierNone ), m_mouse2( false ), m_mouseMoved( false ), m_mouseMovedWhilePressed( false ){
-}
-
-void draw_area(){
- m_window_update( getDeviceArea() );
-}
-
-void testSelect( DeviceVector position ){
- RadiantSelectionSystem::EModifier modifier = modifier_for_state( m_state );
- if ( modifier != RadiantSelectionSystem::eManipulator ) {
- DeviceVector delta( position - m_start );
- if ( fabs( delta.x() ) > m_epsilon.x() && fabs( delta.y() ) > m_epsilon.y() ) {
- DeviceVector delta( position - m_start );
- //getSelectionSystem().SelectArea( *m_view, &m_start[0], &delta[0], modifier, ( m_state & c_modifier_face ) != c_modifierNone );
- getSelectionSystem().SelectArea( *m_view, &m_start[0], &delta[0], RadiantSelectionSystem::eToggle, ( m_state & c_modifier_face ) != c_modifierNone );
- }
- else if( !m_mouseMovedWhilePressed ){
- if ( modifier == RadiantSelectionSystem::eReplace && !m_mouseMoved ) {
- modifier = RadiantSelectionSystem::eCycle;
- }
- getSelectionSystem().SelectPoint( *m_view, &position[0], &m_epsilon[0], modifier, ( m_state & c_modifier_face ) != c_modifierNone );
- }
- }
-
- m_start = m_current = DeviceVector( 0.0f, 0.0f );
- draw_area();
-}
-
-void testSelect_simpleM1( DeviceVector position ){
- /*RadiantSelectionSystem::EModifier modifier = RadiantSelectionSystem::eReplace;
- DeviceVector delta( position - m_start );
- if ( fabs( delta.x() ) < m_epsilon.x() && fabs( delta.y() ) < m_epsilon.y() ) {
- modifier = RadiantSelectionSystem::eCycle;
- }
- getSelectionSystem().SelectPoint( *m_view, &position[0], &m_epsilon[0], modifier, false );*/
- getSelectionSystem().SelectPoint( *m_view, &position[0], &m_epsilon[0], m_mouseMoved ? RadiantSelectionSystem::eReplace : RadiantSelectionSystem::eCycle, false );
- m_start = m_current = device_constrained( position );
-}
-
-
-bool selecting() const {
- return m_state != c_modifier_manipulator && m_mouse2;
-}
-
-void setState( ModifierFlags state ){
- bool was_selecting = selecting();
- m_state = state;
- if ( was_selecting ^ selecting() ) {
- draw_area();
- }
-}
-
-ModifierFlags getState() const {
- return m_state;
-}
-
-void modifierEnable( ModifierFlags type ){
- setState( bitfield_enable( getState(), type ) );
-}
-void modifierDisable( ModifierFlags type ){
- setState( bitfield_disable( getState(), type ) );
-}
-
-void mouseDown( DeviceVector position ){
- m_start = m_current = device_constrained( position );
- if( !m_mouse2 && m_state != c_modifierNone ){
- m_paintSelect = getSelectionSystem().SelectPoint_InitPaint( *m_view, &position[0], &m_epsilon[0], ( m_state & c_modifier_face ) != c_modifierNone );
- }
-}
-
-void mouseMoved( DeviceVector position ){
- m_current = device_constrained( position );
- m_mouseMovedWhilePressed = true;
- if( m_mouse2 ){
- draw_area();
- }
- else if( m_state != c_modifier_manipulator ){
- getSelectionSystem().SelectPoint( *m_view, &m_current[0], &m_epsilon[0],
- m_paintSelect ? RadiantSelectionSystem::eSelect : RadiantSelectionSystem::eDeselect,
- ( m_state & c_modifier_face ) != c_modifierNone );
- }
-}
-typedef MemberCaller<Selector_, void(DeviceVector), &Selector_::mouseMoved> MouseMovedCaller;
-
-void mouseUp( DeviceVector position ){
- if( m_mouse2 ){
- testSelect( device_constrained( position ) );
- }
- else{
- m_start = m_current = DeviceVector( 0.0f, 0.0f );
- }
-
- g_mouseMovedCallback.clear();
- g_mouseUpCallback.clear();
-}
-typedef MemberCaller<Selector_, void(DeviceVector), &Selector_::mouseUp> MouseUpCaller;
-};
-
-
-class Manipulator_
-{
-public:
-DeviceVector m_epsilon;
-const View* m_view;
-ModifierFlags m_state;
-
-Manipulator_() : m_state( c_modifierNone ){
-}
-
-bool mouseDown( DeviceVector position ){
- return getSelectionSystem().SelectManipulator( *m_view, &position[0], &m_epsilon[0] );
-}
-
-void mouseMoved( DeviceVector position ){
- getSelectionSystem().MoveSelected( *m_view, &position[0], ( m_state & c_modifierShift ) == c_modifierShift );
-}
-typedef MemberCaller<Manipulator_, void(DeviceVector), &Manipulator_::mouseMoved> MouseMovedCaller;
-
-void mouseUp( DeviceVector position ){
- getSelectionSystem().endMove();
- g_mouseMovedCallback.clear();
- g_mouseUpCallback.clear();
-}
-<<<<<<< HEAD
-typedef MemberCaller<Manipulator_, void(DeviceVector), &Manipulator_::mouseUp> MouseUpCaller;
-=======
-typedef MemberCaller1<Manipulator_, DeviceVector, &Manipulator_::mouseUp> MouseUpCaller;
-
-void setState( ModifierFlags state ){
- m_state = state;
-}
-
-ModifierFlags getState() const {
- return m_state;
-}
-
-void modifierEnable( ModifierFlags type ){
- setState( bitfield_enable( getState(), type ) );
-}
-void modifierDisable( ModifierFlags type ){
- setState( bitfield_disable( getState(), type ) );
-}
->>>>>>> 3a78d902017a780e65f21f12c709aa746dfcab84
-};
-
-void Scene_copyClosestTexture( SelectionTest& test );
-void Scene_applyClosestTexture( SelectionTest& test );
-
-class RadiantWindowObserver : public SelectionSystemWindowObserver
-{
-enum
-{
- SELECT_EPSILON = 8,
-};
-
-int m_width;
-int m_height;
-
-bool m_mouse_down;
-
-public:
-Selector_ m_selector;
-Manipulator_ m_manipulator;
-
-RadiantWindowObserver() : m_mouse_down( false ){
-}
-void release(){
- delete this;
-}
-void setView( const View& view ){
- m_selector.m_view = &view;
- m_manipulator.m_view = &view;
-}
-void setRectangleDrawCallback( const RectangleCallback& callback ){
- m_selector.m_window_update = callback;
-}
-void onSizeChanged( int width, int height ){
- m_width = width;
- m_height = height;
- DeviceVector epsilon( SELECT_EPSILON / static_cast<float>( m_width ), SELECT_EPSILON / static_cast<float>( m_height ) );
- m_selector.m_epsilon = m_manipulator.m_epsilon = epsilon;
-}
-void onMouseDown( const WindowVector& position, ButtonIdentifier button, ModifierFlags modifiers ){
- if ( button == c_button_select || ( button == c_button_select2 && modifiers != c_modifierNone ) ) {
- m_mouse_down = true;
- //m_selector.m_mouseMoved = false;
-
- DeviceVector devicePosition( window_to_normalised_device( position, m_width, m_height ) );
- if ( modifiers == c_modifier_manipulator && m_manipulator.mouseDown( devicePosition ) ) {
- g_mouseMovedCallback.insert( MouseEventCallback( Manipulator_::MouseMovedCaller( m_manipulator ) ) );
- g_mouseUpCallback.insert( MouseEventCallback( Manipulator_::MouseUpCaller( m_manipulator ) ) );
- }
- else
- {
- if ( button == c_button_select ) {
- m_selector.m_mouse2 = false;
- }
- else{
- m_selector.m_mouse2 = true;
- }
- m_selector.mouseDown( devicePosition );
- g_mouseMovedCallback.insert( MouseEventCallback( Selector_::MouseMovedCaller( m_selector ) ) );
- g_mouseUpCallback.insert( MouseEventCallback( Selector_::MouseUpCaller( m_selector ) ) );
- }
- }
- else if ( button == c_button_texture ) {
- DeviceVector devicePosition( device_constrained( window_to_normalised_device( position, m_width, m_height ) ) );
-
- View scissored( *m_selector.m_view );
- ConstructSelectionTest( scissored, SelectionBoxForPoint( &devicePosition[0], &m_selector.m_epsilon[0] ) );
- SelectionVolume volume( scissored );
-
- if ( modifiers == c_modifier_apply_texture1 || modifiers == c_modifier_apply_texture2 || modifiers == c_modifier_apply_texture3 ) {
- Scene_applyClosestTexture( volume );
- }
- else if ( modifiers == c_modifier_copy_texture ) {
- Scene_copyClosestTexture( volume );
- }
- }
-}
-void onMouseMotion( const WindowVector& position, ModifierFlags modifiers ){
- m_selector.m_mouseMoved = true;
- if ( m_mouse_down && !g_mouseMovedCallback.empty() ) {
- m_selector.m_mouseMovedWhilePressed = true;
- g_mouseMovedCallback.get() ( window_to_normalised_device( position, m_width, m_height ) );
- }
-}
-void onMouseUp( const WindowVector& position, ButtonIdentifier button, ModifierFlags modifiers ){
- if ( ( button == c_button_select || button == c_button_select2 ) && !g_mouseUpCallback.empty() ) {
- m_mouse_down = false;
-
- g_mouseUpCallback.get() ( window_to_normalised_device( position, m_width, m_height ) );
- }
- //L button w/o scene changed = tunnel selection
- if( // !getSelectionSystem().m_undo_begun &&
- modifiers == c_modifierNone && button == c_button_select &&
- //( !m_selector.m_mouseMoved || !m_mouse_down ) &&
- !m_selector.m_mouseMovedWhilePressed &&
- ( getSelectionSystem().Mode() != SelectionSystem::eComponent || getSelectionSystem().ManipulatorMode() != SelectionSystem::eDrag ) ){
- m_selector.testSelect_simpleM1( device_constrained( window_to_normalised_device( position, m_width, m_height ) ) );
- }
- //getSelectionSystem().m_undo_begun = false;
- m_selector.m_mouseMoved = false;
- m_selector.m_mouseMovedWhilePressed = false;
-}
-void onModifierDown( ModifierFlags type ){
- m_selector.modifierEnable( type );
- m_manipulator.modifierEnable( type );
-}
-void onModifierUp( ModifierFlags type ){
- m_selector.modifierDisable( type );
- m_manipulator.modifierDisable( type );
-}
-};
-
-
-
-SelectionSystemWindowObserver* NewWindowObserver(){
- return new RadiantWindowObserver;
-}
-
-
-
-#include "modulesystem/singletonmodule.h"
-#include "modulesystem/moduleregistry.h"
-
-class SelectionDependencies :
- public GlobalSceneGraphModuleRef,
- public GlobalShaderCacheModuleRef,
- public GlobalOpenGLModuleRef
-{
-};
-
-class SelectionAPI : public TypeSystemRef
-{
-SelectionSystem* m_selection;
-public:
-typedef SelectionSystem Type;
-STRING_CONSTANT( Name, "*" );
-
-SelectionAPI(){
- SelectionSystem_Construct();
-
- m_selection = &getSelectionSystem();
-}
-~SelectionAPI(){
- SelectionSystem_Destroy();
-}
-SelectionSystem* getTable(){
- return m_selection;
-}
-};
-
-typedef SingletonModule<SelectionAPI, SelectionDependencies> SelectionModule;
-typedef Static<SelectionModule> StaticSelectionModule;
-StaticRegisterModule staticRegisterSelection( StaticSelectionModule::instance() );
TextureBrowser_createTreeViewTree();
- gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( g_TextureBrowser.m_scr_win_tree ), g_TextureBrowser.m_treeViewTree );
+ //gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( g_TextureBrowser.m_scr_win_tree ), g_TextureBrowser.m_treeViewTree );
+ gtk_container_add( GTK_CONTAINER( g_TextureBrowser.m_scr_win_tree ), GTK_WIDGET( g_TextureBrowser.m_treeViewTree ) );
g_TextureBrowser.m_treeViewTree.show();
}
{ // gl_widget scrollbar
}
{ // tag menu bar
auto menu_tags = ui::Menu(ui::New);
+ gtk_menu_set_title( GTK_MENU( menu_tags ), "Tags" );
// auto tags_item = TextureBrowser_constructTagsMenu( menu_tags );
TextureBrowser_constructTagsMenu( menu_tags );
// gtk_menu_item_set_submenu( GTK_MENU_ITEM( tags_item ), menu_tags );
auto button = toolbar_append_button( toolbar, "Tags", "texbro_tags.png" );
button.dimensions( 22, 22 );
button.connect( "clicked", G_CALLBACK( Popup_View_Menu ), menu_tags );
+
+ //to show detached menu over floating tex bro and main wnd...
+ gtk_menu_attach_to_widget( GTK_MENU( menu_tags ), GTK_WIDGET( button ), NULL );
}
{ // Tag TreeView
g_TextureBrowser.m_scr_win_tags = ui::ScrolledWindow(ui::New);
auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_treeViewTags );
gtk_tree_selection_set_mode( selection, GTK_SELECTION_MULTIPLE );
- gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( g_TextureBrowser.m_scr_win_tags ), g_TextureBrowser.m_treeViewTags );
+ //gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( g_TextureBrowser.m_scr_win_tags ), g_TextureBrowser.m_treeViewTags );
+ gtk_container_add( GTK_CONTAINER( g_TextureBrowser.m_scr_win_tags ), GTK_WIDGET( g_TextureBrowser.m_treeViewTags ) );
g_TextureBrowser.m_treeViewTags.show();
}
{ // Texture/Tag notebook
g_TextureBrowser.m_assigned_tree.show();
scrolled_win.show();
- gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( scrolled_win ), g_TextureBrowser.m_assigned_tree );
+ //gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( scrolled_win ), g_TextureBrowser.m_assigned_tree );
+ gtk_container_add( GTK_CONTAINER( scrolled_win ), GTK_WIDGET( g_TextureBrowser.m_available_tree ) );
frame_table.attach(scrolled_win, {0, 1, 1, 3}, {GTK_FILL, GTK_FILL});
}
g_TextureBrowser.m_available_tree.show();
scrolled_win.show();
- gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( scrolled_win ), g_TextureBrowser.m_available_tree );
+ //gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( scrolled_win ), g_TextureBrowser.m_available_tree );
+ gtk_container_add( GTK_CONTAINER( scrolled_win ), GTK_WIDGET( g_TextureBrowser.m_available_tree ) );
frame_table.attach(scrolled_win, {2, 3, 1, 3}, {GTK_FILL, GTK_FILL});
}
+++ /dev/null
-/*
- Copyright (C) 1999-2006 Id Software, Inc. and contributors.
- For a list of contributors, see the accompanying CONTRIBUTORS file.
-
- This file is part of GtkRadiant.
-
- GtkRadiant is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- GtkRadiant is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GtkRadiant; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-//
-// Texture Window
-//
-// Leonardo Zide (leo@lokigames.com)
-//
-
-#include "texwindow.h"
-
-#include <gtk/gtk.h>
-
-#include "debugging/debugging.h"
-#include "warnings.h"
-
-#include "defaults.h"
-#include "ifilesystem.h"
-#include "iundo.h"
-#include "igl.h"
-#include "iarchive.h"
-#include "moduleobserver.h"
-
-#include <set>
-#include <string>
-#include <vector>
-
-#include <uilib/uilib.h>
-
-#include "signal/signal.h"
-#include "math/vector.h"
-#include "texturelib.h"
-#include "string/string.h"
-#include "shaderlib.h"
-#include "os/file.h"
-#include "os/path.h"
-#include "stream/memstream.h"
-#include "stream/textfilestream.h"
-#include "stream/stringstream.h"
-#include "cmdlib.h"
-#include "texmanip.h"
-#include "textures.h"
-#include "convert.h"
-
-#include "gtkutil/menu.h"
-#include "gtkutil/nonmodal.h"
-#include "gtkutil/cursor.h"
-#include "gtkutil/widget.h"
-#include "gtkutil/glwidget.h"
-#include "gtkutil/messagebox.h"
-
-#include "error.h"
-#include "map.h"
-#include "qgl.h"
-#include "select.h"
-#include "brush_primit.h"
-#include "brushmanip.h"
-#include "patchmanip.h"
-#include "plugin.h"
-#include "qe3.h"
-#include "gtkdlgs.h"
-#include "gtkmisc.h"
-#include "mainframe.h"
-#include "findtexturedialog.h"
-#include "surfacedialog.h"
-#include "patchdialog.h"
-#include "groupdialog.h"
-#include "preferences.h"
-#include "shaders.h"
-#include "commands.h"
-
-bool TextureBrowser_showWads(){
- return !string_empty( g_pGameDescription->getKeyValue( "show_wads" ) );
-}
-
-void TextureBrowser_queueDraw( TextureBrowser& textureBrowser );
-
-bool string_equal_start( const char* string, StringRange start ){
- return string_equal_n( string, start.first, start.last - start.first );
-}
-
-typedef std::set<CopiedString> TextureGroups;
-
-void TextureGroups_addWad( TextureGroups& groups, const char* archive ){
- if ( extension_equal( path_get_extension( archive ), "wad" ) ) {
-#if 1
- groups.insert( archive );
-#else
- CopiedString archiveBaseName( path_get_filename_start( archive ), path_get_filename_base_end( archive ) );
- groups.insert( archiveBaseName );
-#endif
- }
-}
-
-typedef ReferenceCaller<TextureGroups, void(const char*), TextureGroups_addWad> TextureGroupsAddWadCaller;
-
-namespace
-{
-bool g_TextureBrowser_shaderlistOnly = false;
-bool g_TextureBrowser_fixedSize = true;
-bool g_TextureBrowser_filterMissing = false;
-bool g_TextureBrowser_filterFallback = true;
-bool g_TextureBrowser_enableAlpha = false;
-}
-
-CopiedString g_notex;
-CopiedString g_shadernotex;
-
-bool isMissing(const char* name);
-
-bool isNotex(const char* name);
-
-bool isMissing(const char* name){
- if ( string_equal( g_notex.c_str(), name ) ) {
- return true;
- }
- if ( string_equal( g_shadernotex.c_str(), name ) ) {
- return true;
- }
- return false;
-}
-
-bool isNotex(const char* name){
- if ( string_equal_suffix( name, "/" DEFAULT_NOTEX_BASENAME ) ) {
- return true;
- }
- if ( string_equal_suffix( name, "/" DEFAULT_SHADERNOTEX_BASENAME ) ) {
- return true;
- }
- return false;
-}
-
-void TextureGroups_addShader( TextureGroups& groups, const char* shaderName ){
- const char* texture = path_make_relative( shaderName, "textures/" );
-
- // hide notex / shadernotex images
- if ( g_TextureBrowser_filterFallback ) {
- if ( isNotex( shaderName ) ) {
- return;
- }
- if ( isNotex( texture ) ) {
- return;
- }
- }
-
- if ( texture != shaderName ) {
- const char* last = path_remove_directory( texture );
- if ( !string_empty( last ) ) {
- groups.insert( CopiedString( StringRange( texture, --last ) ) );
- }
- }
-}
-
-typedef ReferenceCaller<TextureGroups, void(const char*), TextureGroups_addShader> TextureGroupsAddShaderCaller;
-
-void TextureGroups_addDirectory( TextureGroups& groups, const char* directory ){
- groups.insert( directory );
-}
-
-typedef ReferenceCaller<TextureGroups, void(const char*), TextureGroups_addDirectory> TextureGroupsAddDirectoryCaller;
-
-class DeferredAdjustment
-{
-gdouble m_value;
-guint m_handler;
-
-typedef void ( *ValueChangedFunction )( void* data, gdouble value );
-
-ValueChangedFunction m_function;
-void* m_data;
-
-static gboolean deferred_value_changed( gpointer data ){
- reinterpret_cast<DeferredAdjustment*>( data )->m_function(
- reinterpret_cast<DeferredAdjustment*>( data )->m_data,
- reinterpret_cast<DeferredAdjustment*>( data )->m_value
- );
- reinterpret_cast<DeferredAdjustment*>( data )->m_handler = 0;
- reinterpret_cast<DeferredAdjustment*>( data )->m_value = 0;
- return FALSE;
-}
-
-public:
-DeferredAdjustment( ValueChangedFunction function, void* data ) : m_value( 0 ), m_handler( 0 ), m_function( function ), m_data( data ){
-}
-
-void flush(){
- if ( m_handler != 0 ) {
- g_source_remove( m_handler );
- deferred_value_changed( this );
- }
-}
-
-void value_changed( gdouble value ){
- m_value = value;
- if ( m_handler == 0 ) {
- m_handler = g_idle_add( deferred_value_changed, this );
- }
-}
-
-static void adjustment_value_changed(ui::Adjustment adjustment, DeferredAdjustment* self ){
- self->value_changed( gtk_adjustment_get_value(adjustment) );
-}
-};
-
-
-class TextureBrowser;
-
-typedef ReferenceCaller<TextureBrowser, void(), TextureBrowser_queueDraw> TextureBrowserQueueDrawCaller;
-
-void TextureBrowser_scrollChanged( void* data, gdouble value );
-
-
-enum StartupShaders
-{
- STARTUPSHADERS_NONE = 0,
- STARTUPSHADERS_COMMON,
-};
-
-void TextureBrowser_hideUnusedExport( const Callback<void(bool)> & importer );
-
-typedef FreeCaller<void(const Callback<void(bool)> &), TextureBrowser_hideUnusedExport> TextureBrowserHideUnusedExport;
-
-void TextureBrowser_showShadersExport( const Callback<void(bool)> & importer );
-
-typedef FreeCaller<void(const Callback<void(bool)> &), TextureBrowser_showShadersExport> TextureBrowserShowShadersExport;
-
-void TextureBrowser_showTexturesExport( const Callback<void(bool)> & importer );
-
-typedef FreeCaller<void(const Callback<void(bool)> &), TextureBrowser_showTexturesExport> TextureBrowserShowTexturesExport;
-
-void TextureBrowser_showShaderlistOnly( const Callback<void(bool)> & importer );
-
-typedef FreeCaller<void(const Callback<void(bool)> &), TextureBrowser_showShaderlistOnly> TextureBrowserShowShaderlistOnlyExport;
-
-void TextureBrowser_fixedSize( const Callback<void(bool)> & importer );
-
-typedef FreeCaller<void(const Callback<void(bool)> &), TextureBrowser_fixedSize> TextureBrowserFixedSizeExport;
-
-void TextureBrowser_filterMissing( const Callback<void(bool)> & importer );
-
-typedef FreeCaller<void(const Callback<void(bool)> &), TextureBrowser_filterMissing> TextureBrowserFilterMissingExport;
-
-void TextureBrowser_filterFallback( const Callback<void(bool)> & importer );
-
-typedef FreeCaller<void(const Callback<void(bool)> &), TextureBrowser_filterFallback> TextureBrowserFilterFallbackExport;
-
-void TextureBrowser_enableAlpha( const Callback<void(bool)> & importer );
-
-typedef FreeCaller<void(const Callback<void(bool)> &), TextureBrowser_enableAlpha> TextureBrowserEnableAlphaExport;
-
-class TextureBrowser
-{
-public:
-int width, height;
-int originy;
-int m_nTotalHeight;
-
-CopiedString shader;
-
-ui::Window m_parent{ui::null};
-ui::GLArea m_gl_widget{ui::null};
-ui::Widget m_texture_scroll{ui::null};
-ui::TreeView m_treeViewTree{ui::New};
-ui::TreeView m_treeViewTags{ui::null};
-ui::Frame m_tag_frame{ui::null};
-ui::ListStore m_assigned_store{ui::null};
-ui::ListStore m_available_store{ui::null};
-ui::TreeView m_assigned_tree{ui::null};
-ui::TreeView m_available_tree{ui::null};
-ui::Widget m_scr_win_tree{ui::null};
-ui::Widget m_scr_win_tags{ui::null};
-ui::Widget m_tag_notebook{ui::null};
-ui::Button m_search_button{ui::null};
-ui::Widget m_shader_info_item{ui::null};
-
-std::set<CopiedString> m_all_tags;
-ui::ListStore m_all_tags_list{ui::null};
-std::vector<CopiedString> m_copied_tags;
-std::set<CopiedString> m_found_shaders;
-
-ToggleItem m_hideunused_item;
-ToggleItem m_hidenotex_item;
-ToggleItem m_showshaders_item;
-ToggleItem m_showtextures_item;
-ToggleItem m_showshaderlistonly_item;
-ToggleItem m_fixedsize_item;
-ToggleItem m_filternotex_item;
-ToggleItem m_enablealpha_item;
-
-guint m_sizeHandler;
-guint m_exposeHandler;
-
-bool m_heightChanged;
-bool m_originInvalid;
-
-DeferredAdjustment m_scrollAdjustment;
-FreezePointer m_freezePointer;
-
-Vector3 color_textureback;
-// the increment step we use against the wheel mouse
-std::size_t m_mouseWheelScrollIncrement;
-std::size_t m_textureScale;
-// make the texture increments match the grid changes
-bool m_showShaders;
-bool m_showTextures;
-bool m_showTextureScrollbar;
-StartupShaders m_startupShaders;
-// if true, the texture window will only display in-use shaders
-// if false, all the shaders in memory are displayed
-bool m_hideUnused;
-bool m_rmbSelected;
-bool m_searchedTags;
-bool m_tags;
-bool m_move_started;
-// The uniform size (in pixels) that textures are resized to when m_resizeTextures is true.
-int m_uniformTextureSize;
-int m_uniformTextureMinSize;
-
-<<<<<<< HEAD
-=======
-bool m_hideNonShadersInCommon;
->>>>>>> 3a78d902017a780e65f21f12c709aa746dfcab84
-// Return the display width of a texture in the texture browser
-void getTextureWH( qtexture_t* tex, int &W, int &H ){
- // Don't use uniform size
- W = (int)( tex->width * ( (float)m_textureScale / 100 ) );
- H = (int)( tex->height * ( (float)m_textureScale / 100 ) );
- if ( W < 1 ) W = 1;
- if ( H < 1 ) H = 1;
-
- if ( g_TextureBrowser_fixedSize ){
- if ( W >= H ) {
- // Texture is square, or wider than it is tall
- if ( W >= m_uniformTextureSize ){
- H = m_uniformTextureSize * H / W;
- W = m_uniformTextureSize;
- }
- else if ( W <= m_uniformTextureMinSize ){
- H = m_uniformTextureMinSize * H / W;
- W = m_uniformTextureMinSize;
- }
- }
- else {
- // Texture taller than it is wide
- if ( H >= m_uniformTextureSize ){
- W = m_uniformTextureSize * W / H;
- H = m_uniformTextureSize;
- }
- else if ( H <= m_uniformTextureMinSize ){
- W = m_uniformTextureMinSize * W / H;
- H = m_uniformTextureMinSize;
- }
- }
- }
-}
-
-TextureBrowser() :
- m_texture_scroll( ui::null ),
- m_hideunused_item( TextureBrowserHideUnusedExport() ),
- m_hidenotex_item( TextureBrowserFilterFallbackExport() ),
- m_showshaders_item( TextureBrowserShowShadersExport() ),
- m_showtextures_item( TextureBrowserShowTexturesExport() ),
- m_showshaderlistonly_item( TextureBrowserShowShaderlistOnlyExport() ),
- m_fixedsize_item( TextureBrowserFixedSizeExport() ),
- m_filternotex_item( TextureBrowserFilterMissingExport() ),
- m_enablealpha_item( TextureBrowserEnableAlphaExport() ),
- m_heightChanged( true ),
- m_originInvalid( true ),
- m_scrollAdjustment( TextureBrowser_scrollChanged, this ),
- color_textureback( 0.25f, 0.25f, 0.25f ),
- m_mouseWheelScrollIncrement( 64 ),
- m_textureScale( 50 ),
- m_showShaders( true ),
- m_showTextures( true ),
- m_showTextureScrollbar( true ),
- m_startupShaders( STARTUPSHADERS_NONE ),
- m_hideUnused( false ),
- m_rmbSelected( false ),
- m_searchedTags( false ),
- m_tags( false ),
- m_uniformTextureSize( 160 ),
- m_uniformTextureMinSize( 48 ),
- m_hideNonShadersInCommon( true ),
- m_move_started( false ){
-}
-};
-
-void ( *TextureBrowser_textureSelected )( const char* shader );
-
-
-void TextureBrowser_updateScroll( TextureBrowser& textureBrowser );
-
-
-const char* TextureBrowser_getComonShadersName(){
- const char* value = g_pGameDescription->getKeyValue( "common_shaders_name" );
- if ( !string_empty( value ) ) {
- return value;
- }
- return "Common";
-}
-
-const char* TextureBrowser_getComonShadersDir(){
- const char* value = g_pGameDescription->getKeyValue( "common_shaders_dir" );
- if ( !string_empty( value ) ) {
- return value;
- }
- return "common/";
-}
-
-inline int TextureBrowser_fontHeight( TextureBrowser& textureBrowser ){
- return GlobalOpenGL().m_font->getPixelHeight();
-}
-
-const char* TextureBrowser_GetSelectedShader( TextureBrowser& textureBrowser ){
- return textureBrowser.shader.c_str();
-}
-
-void TextureBrowser_SetStatus( TextureBrowser& textureBrowser, const char* name ){
- IShader* shader = QERApp_Shader_ForName( name );
- qtexture_t* q = shader->getTexture();
- StringOutputStream strTex( 256 );
- strTex << name << " W: " << Unsigned( q->width ) << " H: " << Unsigned( q->height );
- shader->DecRef();
- g_pParentWnd->SetStatusText( g_pParentWnd->m_texture_status, strTex.c_str() );
-}
-
-void TextureBrowser_Focus( TextureBrowser& textureBrowser, const char* name );
-
-void TextureBrowser_SetSelectedShader( TextureBrowser& textureBrowser, const char* shader ){
- textureBrowser.shader = shader;
- TextureBrowser_SetStatus( textureBrowser, shader );
- TextureBrowser_Focus( textureBrowser, shader );
-
- if ( FindTextureDialog_isOpen() ) {
- FindTextureDialog_selectTexture( shader );
- }
-
- // disable the menu item "shader info" if no shader was selected
- IShader* ishader = QERApp_Shader_ForName( shader );
- CopiedString filename = ishader->getShaderFileName();
-
- if ( filename.empty() ) {
- if ( textureBrowser.m_shader_info_item != NULL ) {
- gtk_widget_set_sensitive( textureBrowser.m_shader_info_item, FALSE );
- }
- }
- else {
- gtk_widget_set_sensitive( textureBrowser.m_shader_info_item, TRUE );
- }
-
- ishader->DecRef();
-}
-
-
-CopiedString g_TextureBrowser_currentDirectory;
-
-/*
- ============================================================================
-
- TEXTURE LAYOUT
-
- TTimo: now based on a rundown through all the shaders
- NOTE: we expect the Active shaders count doesn't change during a Texture_StartPos .. Texture_NextPos cycle
- otherwise we may need to rely on a list instead of an array storage
- ============================================================================
- */
-
-class TextureLayout
-{
-public:
-// texture layout functions
-// TTimo: now based on shaders
-int current_x, current_y, current_row;
-};
-
-void Texture_StartPos( TextureLayout& layout ){
- layout.current_x = 8;
- layout.current_y = -8;
- layout.current_row = 0;
-}
-
-void Texture_NextPos( TextureBrowser& textureBrowser, TextureLayout& layout, qtexture_t* current_texture, int *x, int *y ){
- qtexture_t* q = current_texture;
-
- int nWidth, nHeight;
- textureBrowser.getTextureWH( q, nWidth, nHeight );
- if ( layout.current_x + nWidth > textureBrowser.width - 8 && layout.current_row ) { // go to the next row unless the texture is the first on the row
- layout.current_x = 8;
- layout.current_y -= layout.current_row + TextureBrowser_fontHeight( textureBrowser ) + 4;//+4
- layout.current_row = 0;
- }
-
- *x = layout.current_x;
- *y = layout.current_y;
-
- // Is our texture larger than the row? If so, grow the
- // row height to match it
-
- if ( layout.current_row < nHeight ) {
- layout.current_row = nHeight;
- }
-
- // never go less than 96, or the names get all crunched up
- layout.current_x += nWidth < 96 ? 96 : nWidth;
- layout.current_x += 8;
-}
-
-bool TextureSearch_IsShown( const char* name ){
- std::set<CopiedString>::iterator iter;
-
- iter = GlobalTextureBrowser().m_found_shaders.find( name );
-
- if ( iter == GlobalTextureBrowser().m_found_shaders.end() ) {
- return false;
- }
- else {
- return true;
- }
-}
-
-// if texture_showinuse jump over non in-use textures
-<<<<<<< HEAD
-bool Texture_IsShown( IShader* shader, bool show_shaders, bool show_textures, bool hideUnused ){
- // filter missing shaders
- // ugly: filter on built-in fallback name after substitution
- if ( g_TextureBrowser_filterMissing ) {
- if ( isMissing( shader->getTexture()->name ) ) {
- return false;
- }
- }
- // filter the fallback (notex/shadernotex) for missing shaders or editor image
- if ( g_TextureBrowser_filterFallback ) {
- if ( isNotex( shader->getName() ) ) {
- return false;
- }
- if ( isNotex( shader->getTexture()->name ) ) {
- return false;
- }
-=======
-bool Texture_IsShown( IShader* shader, bool show_shaders, bool show_textures, bool hideUnused, bool hideNonShadersInCommon ){
- // filter notex / shadernotex images
- if ( g_TextureBrowser_filterNotex && ( string_equal( g_notex.c_str(), shader->getTexture()->name ) || string_equal( g_shadernotex.c_str(), shader->getTexture()->name ) ) ) {
- return false;
->>>>>>> 3a78d902017a780e65f21f12c709aa746dfcab84
- }
-
- if ( g_TextureBrowser_currentDirectory == "Untagged" ) {
- std::set<CopiedString>::iterator iter;
-
- iter = GlobalTextureBrowser().m_found_shaders.find( shader->getName() );
-
- if ( iter == GlobalTextureBrowser().m_found_shaders.end() ) {
- return false;
- }
- else {
- return true;
- }
- }
-
- if ( !shader_equal_prefix( shader->getName(), "textures/" ) ) {
- return false;
- }
-
- if ( !show_shaders && !shader->IsDefault() ) {
- return false;
- }
-
- if ( !show_textures && shader->IsDefault() ) {
- return false;
- }
-
- if ( hideUnused && !shader->IsInUse() ) {
- return false;
- }
-
- if( hideNonShadersInCommon && shader->IsDefault() && !shader->IsInUse() //&& g_TextureBrowser_currentDirectory != ""
- && shader_equal_prefix( shader_get_textureName( shader->getName() ), TextureBrowser_getComonShadersDir() ) ){
- return false;
- }
-
- if ( GlobalTextureBrowser().m_searchedTags ) {
- if ( !TextureSearch_IsShown( shader->getName() ) ) {
- return false;
- }
- else {
- return true;
- }
- }
- else {
- if ( !shader_equal_prefix( shader_get_textureName( shader->getName() ), g_TextureBrowser_currentDirectory.c_str() ) ) {
- return false;
- }
- }
-
- return true;
-}
-
-void TextureBrowser_heightChanged( TextureBrowser& textureBrowser ){
- textureBrowser.m_heightChanged = true;
-
- TextureBrowser_updateScroll( textureBrowser );
- TextureBrowser_queueDraw( textureBrowser );
-}
-
-void TextureBrowser_evaluateHeight( TextureBrowser& textureBrowser ){
- if ( textureBrowser.m_heightChanged ) {
- textureBrowser.m_heightChanged = false;
-
- textureBrowser.m_nTotalHeight = 0;
-
- TextureLayout layout;
- Texture_StartPos( layout );
- for ( QERApp_ActiveShaders_IteratorBegin(); !QERApp_ActiveShaders_IteratorAtEnd(); QERApp_ActiveShaders_IteratorIncrement() )
- {
- IShader* shader = QERApp_ActiveShaders_IteratorCurrent();
-
- if ( !Texture_IsShown( shader, textureBrowser.m_showShaders, textureBrowser.m_showTextures, textureBrowser.m_hideUnused, textureBrowser.m_hideNonShadersInCommon ) ) {
- continue;
- }
-
- int x, y;
- Texture_NextPos( textureBrowser, layout, shader->getTexture(), &x, &y );
- int nWidth, nHeight;
- textureBrowser.getTextureWH( shader->getTexture(), nWidth, nHeight );
- textureBrowser.m_nTotalHeight = std::max( textureBrowser.m_nTotalHeight, abs( layout.current_y ) + TextureBrowser_fontHeight( textureBrowser ) + nHeight + 4 );
- }
- }
-}
-
-int TextureBrowser_TotalHeight( TextureBrowser& textureBrowser ){
- TextureBrowser_evaluateHeight( textureBrowser );
- return textureBrowser.m_nTotalHeight;
-}
-
-inline const int& min_int( const int& left, const int& right ){
- return std::min( left, right );
-}
-
-void TextureBrowser_clampOriginY( TextureBrowser& textureBrowser ){
- if ( textureBrowser.originy > 0 ) {
- textureBrowser.originy = 0;
- }
- int lower = min_int( textureBrowser.height - TextureBrowser_TotalHeight( textureBrowser ), 0 );
- if ( textureBrowser.originy < lower ) {
- textureBrowser.originy = lower;
- }
-}
-
-int TextureBrowser_getOriginY( TextureBrowser& textureBrowser ){
- if ( textureBrowser.m_originInvalid ) {
- textureBrowser.m_originInvalid = false;
- TextureBrowser_clampOriginY( textureBrowser );
- TextureBrowser_updateScroll( textureBrowser );
- }
- return textureBrowser.originy;
-}
-
-void TextureBrowser_setOriginY( TextureBrowser& textureBrowser, int originy ){
- textureBrowser.originy = originy;
- TextureBrowser_clampOriginY( textureBrowser );
- TextureBrowser_updateScroll( textureBrowser );
- TextureBrowser_queueDraw( textureBrowser );
-}
-
-
-Signal0 g_activeShadersChangedCallbacks;
-
-void TextureBrowser_addActiveShadersChangedCallback( const SignalHandler& handler ){
- g_activeShadersChangedCallbacks.connectLast( handler );
-}
-
-void TextureBrowser_constructTreeStore();
-
-class ShadersObserver : public ModuleObserver
-{
-Signal0 m_realiseCallbacks;
-public:
-void realise(){
- m_realiseCallbacks();
- /* texturebrowser tree update on vfs restart */
-// TextureBrowser_constructTreeStore();
-}
-
-void unrealise(){
-}
-
-void insert( const SignalHandler& handler ){
- m_realiseCallbacks.connectLast( handler );
-}
-};
-
-namespace
-{
-ShadersObserver g_ShadersObserver;
-}
-
-void TextureBrowser_addShadersRealiseCallback( const SignalHandler& handler ){
- g_ShadersObserver.insert( handler );
-}
-
-void TextureBrowser_activeShadersChanged( TextureBrowser& textureBrowser ){
- TextureBrowser_heightChanged( textureBrowser );
- textureBrowser.m_originInvalid = true;
-
- g_activeShadersChangedCallbacks();
-}
-
-struct TextureBrowser_ShowScrollbar {
- static void Export(const TextureBrowser &self, const Callback<void(bool)> &returnz) {
- returnz(self.m_showTextureScrollbar);
- }
-
- static void Import(TextureBrowser &self, bool value) {
- self.m_showTextureScrollbar = value;
- if (self.m_texture_scroll) {
- self.m_texture_scroll.visible(self.m_showTextureScrollbar);
- TextureBrowser_updateScroll(self);
- }
- }
-};
-
-
-/*
- ==============
- TextureBrowser_ShowDirectory
- relies on texture_directory global for the directory to use
- 1) Load the shaders for the given directory
- 2) Scan the remaining texture, load them and assign them a default shader (the "noshader" shader)
- NOTE: when writing a texture plugin, or some texture extensions, this function may need to be overriden, and made
- available through the IShaders interface
- NOTE: for texture window layout:
- all shaders are stored with alphabetical order after load
- previously loaded and displayed stuff is hidden, only in-use and newly loaded is shown
- ( the GL textures are not flushed though)
- ==============
- */
-
-bool endswith( const char *haystack, const char *needle ){
- size_t lh = strlen( haystack );
- size_t ln = strlen( needle );
- if ( lh < ln ) {
- return false;
- }
- return !memcmp( haystack + ( lh - ln ), needle, ln );
-}
-
-bool texture_name_ignore( const char* name ){
- StringOutputStream strTemp( string_length( name ) );
- strTemp << LowerCase( name );
-
- return
- endswith( strTemp.c_str(), ".specular" ) ||
- endswith( strTemp.c_str(), ".glow" ) ||
- endswith( strTemp.c_str(), ".bump" ) ||
- endswith( strTemp.c_str(), ".diffuse" ) ||
- endswith( strTemp.c_str(), ".blend" ) ||
- endswith( strTemp.c_str(), ".alpha" ) ||
- endswith( strTemp.c_str(), "_alpha" ) ||
- /* Quetoo */
- endswith( strTemp.c_str(), "_h" ) ||
- endswith( strTemp.c_str(), "_local" ) ||
- endswith( strTemp.c_str(), "_nm" ) ||
- endswith( strTemp.c_str(), "_s" ) ||
- /* DarkPlaces */
- endswith( strTemp.c_str(), "_bump" ) ||
- endswith( strTemp.c_str(), "_glow" ) ||
- endswith( strTemp.c_str(), "_gloss" ) ||
- endswith( strTemp.c_str(), "_luma" ) ||
- endswith( strTemp.c_str(), "_norm" ) ||
- endswith( strTemp.c_str(), "_pants" ) ||
- endswith( strTemp.c_str(), "_shirt" ) ||
- endswith( strTemp.c_str(), "_reflect" ) ||
- /* Unvanquished */
- endswith( strTemp.c_str(), "_d" ) ||
- endswith( strTemp.c_str(), "_n" ) ||
- endswith( strTemp.c_str(), "_p" ) ||
- endswith( strTemp.c_str(), "_g" ) ||
- endswith( strTemp.c_str(), "_a" ) ||
- 0;
-}
-
-class LoadShaderVisitor : public Archive::Visitor
-{
-public:
-void visit( const char* name ){
- IShader* shader = QERApp_Shader_ForName( CopiedString( StringRange( name, path_get_filename_base_end( name ) ) ).c_str() );
- shader->DecRef();
-}
-};
-
-void TextureBrowser_SetHideUnused( TextureBrowser& textureBrowser, bool hideUnused );
-
-ui::Widget g_page_textures{ui::null};
-
-void TextureBrowser_toggleShow(){
- GroupDialog_showPage( g_page_textures );
-}
-
-
-void TextureBrowser_updateTitle(){
- GroupDialog_updatePageTitle( g_page_textures );
-}
-
-
-class TextureCategoryLoadShader
-{
-const char* m_directory;
-std::size_t& m_count;
-public:
-using func = void(const char *);
-
-TextureCategoryLoadShader( const char* directory, std::size_t& count )
- : m_directory( directory ), m_count( count ){
- m_count = 0;
-}
-
-void operator()( const char* name ) const {
- if ( shader_equal_prefix( name, "textures/" )
- && shader_equal_prefix( name + string_length( "textures/" ), m_directory ) ) {
- ++m_count;
- // request the shader, this will load the texture if needed
- // this Shader_ForName call is a kind of hack
- IShader *pFoo = QERApp_Shader_ForName( name );
- pFoo->DecRef();
- }
-}
-};
-
-void TextureDirectory_loadTexture( const char* directory, const char* texture ){
- StringOutputStream name( 256 );
- name << directory << StringRange( texture, path_get_filename_base_end( texture ) );
-
- if ( texture_name_ignore( name.c_str() ) ) {
- return;
- }
-
- if ( !shader_valid( name.c_str() ) ) {
- globalOutputStream() << "Skipping invalid texture name: [" << name.c_str() << "]\n";
- return;
- }
-
- // if a texture is already in use to represent a shader, ignore it
- IShader* shader = QERApp_Shader_ForName( name.c_str() );
- shader->DecRef();
-}
-
-typedef ConstPointerCaller<char, void(const char*), TextureDirectory_loadTexture> TextureDirectoryLoadTextureCaller;
-
-class LoadTexturesByTypeVisitor : public ImageModules::Visitor
-{
-const char* m_dirstring;
-public:
-LoadTexturesByTypeVisitor( const char* dirstring )
- : m_dirstring( dirstring ){
-}
-
-void visit( const char* minor, const _QERPlugImageTable& table ) const {
- GlobalFileSystem().forEachFile( m_dirstring, minor, TextureDirectoryLoadTextureCaller( m_dirstring ) );
-}
-};
-
-void TextureBrowser_ShowDirectory( TextureBrowser& textureBrowser, const char* directory ){
- if ( TextureBrowser_showWads() ) {
- Archive* archive = GlobalFileSystem().getArchive( directory );
- ASSERT_NOTNULL( archive );
- LoadShaderVisitor visitor;
- archive->forEachFile( Archive::VisitorFunc( visitor, Archive::eFiles, 0 ), "textures/" );
- }
- else
- {
- g_TextureBrowser_currentDirectory = directory;
- TextureBrowser_heightChanged( textureBrowser );
-
- std::size_t shaders_count;
- GlobalShaderSystem().foreachShaderName(makeCallback( TextureCategoryLoadShader( directory, shaders_count ) ) );
- globalOutputStream() << "Showing " << Unsigned( shaders_count ) << " shaders.\n";
-
- if ( g_pGameDescription->mGameType != "doom3" ) {
- // load remaining texture files
-
- StringOutputStream dirstring( 64 );
- dirstring << "textures/" << directory;
-
- Radiant_getImageModules().foreachModule( LoadTexturesByTypeVisitor( dirstring.c_str() ) );
- }
- }
-
- // we'll display the newly loaded textures + all the ones already in use
- TextureBrowser_SetHideUnused( textureBrowser, false );
-
- TextureBrowser_updateTitle();
-}
-
-void TextureBrowser_ShowTagSearchResult( TextureBrowser& textureBrowser, const char* directory ){
- g_TextureBrowser_currentDirectory = directory;
- TextureBrowser_heightChanged( textureBrowser );
-
- std::size_t shaders_count;
- GlobalShaderSystem().foreachShaderName(makeCallback( TextureCategoryLoadShader( directory, shaders_count ) ) );
- globalOutputStream() << "Showing " << Unsigned( shaders_count ) << " shaders.\n";
-
- if ( g_pGameDescription->mGameType != "doom3" ) {
- // load remaining texture files
- StringOutputStream dirstring( 64 );
- dirstring << "textures/" << directory;
-
- {
- LoadTexturesByTypeVisitor visitor( dirstring.c_str() );
- Radiant_getImageModules().foreachModule( visitor );
- }
- }
-
- // we'll display the newly loaded textures + all the ones already in use
- TextureBrowser_SetHideUnused( textureBrowser, false );
-}
-
-
-bool TextureBrowser_hideUnused();
-
-void TextureBrowser_hideUnusedExport( const Callback<void(bool)> & importer ){
- importer( TextureBrowser_hideUnused() );
-}
-
-typedef FreeCaller<void(const Callback<void(bool)> &), TextureBrowser_hideUnusedExport> TextureBrowserHideUnusedExport;
-
-void TextureBrowser_showShadersExport( const Callback<void(bool)> & importer ){
- importer( GlobalTextureBrowser().m_showShaders );
-}
-
-typedef FreeCaller<void(const Callback<void(bool)> &), TextureBrowser_showShadersExport> TextureBrowserShowShadersExport;
-
-void TextureBrowser_showTexturesExport( const Callback<void(bool)> & importer ){
- importer( GlobalTextureBrowser().m_showTextures );
-}
-
-typedef FreeCaller<void(const Callback<void(bool)> &), TextureBrowser_showTexturesExport> TextureBrowserShowTexturesExport;
-
-void TextureBrowser_showShaderlistOnly( const Callback<void(bool)> & importer ){
- importer( g_TextureBrowser_shaderlistOnly );
-}
-
-typedef FreeCaller<void(const Callback<void(bool)> &), TextureBrowser_showShaderlistOnly> TextureBrowserShowShaderlistOnlyExport;
-
-void TextureBrowser_fixedSize( const Callback<void(bool)> & importer ){
- importer( g_TextureBrowser_fixedSize );
-}
-
-typedef FreeCaller<void(const Callback<void(bool)> &), TextureBrowser_fixedSize> TextureBrowser_FixedSizeExport;
-
-void TextureBrowser_filterMissing( const Callback<void(bool)> & importer ){
- importer( g_TextureBrowser_filterMissing );
-}
-
-typedef FreeCaller<void(const Callback<void(bool)> &), TextureBrowser_filterMissing> TextureBrowser_filterMissingExport;
-
-void TextureBrowser_filterFallback( const Callback<void(bool)> & importer ){
- importer( g_TextureBrowser_filterFallback );
-}
-
-typedef FreeCaller<void(const Callback<void(bool)> &), TextureBrowser_filterFallback> TextureBrowser_filterFallbackExport;
-
-void TextureBrowser_enableAlpha( const Callback<void(bool)> & importer ){
- importer( g_TextureBrowser_enableAlpha );
-}
-
-typedef FreeCaller<void(const Callback<void(bool)> &), TextureBrowser_enableAlpha> TextureBrowser_enableAlphaExport;
-
-void TextureBrowser_SetHideUnused( TextureBrowser& textureBrowser, bool hideUnused ){
- textureBrowser.m_hideUnused = hideUnused;
-
- textureBrowser.m_hideunused_item.update();
-
- TextureBrowser_heightChanged( textureBrowser );
- textureBrowser.m_originInvalid = true;
-}
-
-void TextureBrowser_ShowStartupShaders( TextureBrowser& textureBrowser ){
- if ( textureBrowser.m_startupShaders == STARTUPSHADERS_COMMON ) {
- TextureBrowser_ShowDirectory( textureBrowser, TextureBrowser_getComonShadersDir() );
- }
-}
-
-
-//++timo NOTE: this is a mix of Shader module stuff and texture explorer
-// it might need to be split in parts or moved out .. dunno
-// scroll origin so the specified texture is completely on screen
-// if current texture is not displayed, nothing is changed
-void TextureBrowser_Focus( TextureBrowser& textureBrowser, const char* name ){
- TextureLayout layout;
- // scroll origin so the texture is completely on screen
- Texture_StartPos( layout );
-
- for ( QERApp_ActiveShaders_IteratorBegin(); !QERApp_ActiveShaders_IteratorAtEnd(); QERApp_ActiveShaders_IteratorIncrement() )
- {
- IShader* shader = QERApp_ActiveShaders_IteratorCurrent();
-
- if ( !Texture_IsShown( shader, textureBrowser.m_showShaders, textureBrowser.m_showTextures, textureBrowser.m_hideUnused, textureBrowser.m_hideNonShadersInCommon ) ) {
- continue;
- }
-
- int x, y;
- Texture_NextPos( textureBrowser, layout, shader->getTexture(), &x, &y );
- qtexture_t* q = shader->getTexture();
- if ( !q ) {
- break;
- }
-
- // we have found when texdef->name and the shader name match
- // NOTE: as everywhere else for our comparisons, we are not case sensitive
- if ( shader_equal( name, shader->getName() ) ) {
- //int textureHeight = (int)( q->height * ( (float)textureBrowser.m_textureScale / 100 ) ) + 2 * TextureBrowser_fontHeight( textureBrowser );
- int textureWidth, textureHeight;
- textureBrowser.getTextureWH( q, textureWidth, textureHeight );
- textureHeight += 2 * TextureBrowser_fontHeight( textureBrowser );
-
-
- int originy = TextureBrowser_getOriginY( textureBrowser );
- if ( y > originy ) {
- originy = y + 4;
- }
-
- if ( y - textureHeight < originy - textureBrowser.height ) {
- originy = ( y - textureHeight ) + textureBrowser.height;
- }
-
- TextureBrowser_setOriginY( textureBrowser, originy );
- return;
- }
- }
-}
-
-IShader* Texture_At( TextureBrowser& textureBrowser, int mx, int my ){
- my += TextureBrowser_getOriginY( textureBrowser ) - textureBrowser.height;
-
- TextureLayout layout;
- Texture_StartPos( layout );
- for ( QERApp_ActiveShaders_IteratorBegin(); !QERApp_ActiveShaders_IteratorAtEnd(); QERApp_ActiveShaders_IteratorIncrement() )
- {
- IShader* shader = QERApp_ActiveShaders_IteratorCurrent();
-
- if ( !Texture_IsShown( shader, textureBrowser.m_showShaders, textureBrowser.m_showTextures, textureBrowser.m_hideUnused, textureBrowser.m_hideNonShadersInCommon ) ) {
- continue;
- }
-
- int x, y;
- Texture_NextPos( textureBrowser, layout, shader->getTexture(), &x, &y );
- qtexture_t *q = shader->getTexture();
- if ( !q ) {
- break;
- }
-
- int nWidth, nHeight;
- textureBrowser.getTextureWH( q, nWidth, nHeight );
- if ( mx > x && mx - x < nWidth
- && my < y && y - my < nHeight + TextureBrowser_fontHeight( textureBrowser ) ) {
- return shader;
- }
- }
-
- return 0;
-}
-
-/*
- ==============
- SelectTexture
-
- By mouse click
- ==============
- */
-void SelectTexture( TextureBrowser& textureBrowser, int mx, int my, bool bShift ){
- IShader* shader = Texture_At( textureBrowser, mx, my );
- if ( shader != 0 ) {
- if ( bShift ) {
- if ( shader->IsDefault() ) {
- globalOutputStream() << "ERROR: " << shader->getName() << " is not a shader, it's a texture.\n";
- }
- else{
- ViewShader( shader->getShaderFileName(), shader->getName() );
- }
- }
- else
- {
- TextureBrowser_SetSelectedShader( textureBrowser, shader->getName() );
- TextureBrowser_textureSelected( shader->getName() );
-
- if ( !FindTextureDialog_isOpen() && !textureBrowser.m_rmbSelected ) {
- UndoableCommand undo( "textureNameSetSelected" );
- Select_SetShader( shader->getName() );
- }
- }
- }
-}
-
-/*
- ============================================================================
-
- MOUSE ACTIONS
-
- ============================================================================
- */
-
-void TextureBrowser_trackingDelta( int x, int y, unsigned int state, void* data ){
- TextureBrowser& textureBrowser = *reinterpret_cast<TextureBrowser*>( data );
- if ( y != 0 ) {
- int scale = 1;
-
- if ( state & GDK_SHIFT_MASK ) {
- scale = 4;
- }
-
- int originy = TextureBrowser_getOriginY( textureBrowser );
- originy += y * scale;
- TextureBrowser_setOriginY( textureBrowser, originy );
- }
-}
-
-void TextureBrowser_Tracking_MouseUp( TextureBrowser& textureBrowser ){
- textureBrowser.m_move_started = false;
- textureBrowser.m_freezePointer.unfreeze_pointer( textureBrowser.m_parent, false );
-}
-
-void TextureBrowser_Tracking_MouseDown( TextureBrowser& textureBrowser ){
- if( textureBrowser.m_move_started ){
- TextureBrowser_Tracking_MouseUp( textureBrowser );
- }
- textureBrowser.m_move_started = true;
- textureBrowser.m_freezePointer.freeze_pointer( textureBrowser.m_parent, textureBrowser.m_gl_widget, TextureBrowser_trackingDelta, &textureBrowser );
-}
-
-void TextureBrowser_Selection_MouseDown( TextureBrowser& textureBrowser, guint32 flags, int pointx, int pointy ){
- SelectTexture( textureBrowser, pointx, textureBrowser.height - 1 - pointy, ( flags & GDK_SHIFT_MASK ) != 0 );
-}
-
-/*
- ============================================================================
-
- DRAWING
-
- ============================================================================
- */
-
-/*
- ============
- Texture_Draw
- TTimo: relying on the shaders list to display the textures
- we must query all qtexture_t* to manage and display through the IShaders interface
- this allows a plugin to completely override the texture system
- ============
- */
-void Texture_Draw( TextureBrowser& textureBrowser ){
- int originy = TextureBrowser_getOriginY( textureBrowser );
-
- glClearColor( textureBrowser.color_textureback[0],
- textureBrowser.color_textureback[1],
- textureBrowser.color_textureback[2],
- 0 );
- glViewport( 0, 0, textureBrowser.width, textureBrowser.height );
- glMatrixMode( GL_PROJECTION );
- glLoadIdentity();
-
- glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
- glDisable( GL_DEPTH_TEST );
-
- //glDisable( GL_BLEND );
- if ( g_TextureBrowser_enableAlpha ) {
- glEnable( GL_BLEND );
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
- else {
- glDisable( GL_BLEND );
- }
-
- glOrtho( 0, textureBrowser.width, originy - textureBrowser.height, originy, -100, 100 );
- glEnable( GL_TEXTURE_2D );
-
- glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
-
- int last_y = 0, last_height = 0;
-
- TextureLayout layout;
- Texture_StartPos( layout );
- for ( QERApp_ActiveShaders_IteratorBegin(); !QERApp_ActiveShaders_IteratorAtEnd(); QERApp_ActiveShaders_IteratorIncrement() )
- {
- IShader* shader = QERApp_ActiveShaders_IteratorCurrent();
-
- if ( !Texture_IsShown( shader, textureBrowser.m_showShaders, textureBrowser.m_showTextures, textureBrowser.m_hideUnused, textureBrowser.m_hideNonShadersInCommon ) ) {
- continue;
- }
-
- int x, y;
- Texture_NextPos( textureBrowser, layout, shader->getTexture(), &x, &y );
- qtexture_t *q = shader->getTexture();
- if ( !q ) {
- break;
- }
-
- int nWidth, nHeight;
- textureBrowser.getTextureWH( q, nWidth, nHeight );
-
- if ( y != last_y ) {
- last_y = y;
- last_height = 0;
- }
- last_height = std::max( nHeight, last_height );
-
- // Is this texture visible?
- if ( ( y - nHeight - TextureBrowser_fontHeight( textureBrowser ) < originy )
- && ( y > originy - textureBrowser.height ) ) {
- // borders rules:
- // if it's the current texture, draw a thick red line, else:
- // shaders have a white border, simple textures don't
- // if !texture_showinuse: (some textures displayed may not be in use)
- // draw an additional square around with 0.5 1 0.5 color
- glLineWidth( 1 );
- const float xf = (float)x;
- const float yf = (float)( y - TextureBrowser_fontHeight( textureBrowser ) );
- float xfMax = xf + 1.5 + nWidth;
- float xfMin = xf - 1.5;
- float yfMax = yf + 1.5;
- float yfMin = yf - nHeight - 1.5;
-
- //selected texture
- if ( shader_equal( TextureBrowser_GetSelectedShader( textureBrowser ), shader->getName() ) ) {
- glLineWidth( 2 );
- if ( textureBrowser.m_rmbSelected ) {
- glColor3f( 0,0,1 );
- }
- else {
- glColor3f( 1,0,0 );
- }
- xfMax += .5;
- xfMin -= .5;
- yfMax += .5;
- yfMin -= .5;
- glDisable( GL_TEXTURE_2D );
- glBegin( GL_LINE_LOOP );
- glVertex2f( xfMin ,yfMax );
- glVertex2f( xfMin ,yfMin );
- glVertex2f( xfMax ,yfMin );
- glVertex2f( xfMax ,yfMax );
- glEnd();
- glEnable( GL_TEXTURE_2D );
- }
- // highlight in-use textures
- else if ( !textureBrowser.m_hideUnused && shader->IsInUse() ) {
- glColor3f( 0.5,1,0.5 );
- glDisable( GL_TEXTURE_2D );
- glBegin( GL_LINE_LOOP );
- glVertex2f( xfMin ,yfMax );
- glVertex2f( xfMin ,yfMin );
- glVertex2f( xfMax ,yfMin );
- glVertex2f( xfMax ,yfMax );
- glEnd();
- glEnable( GL_TEXTURE_2D );
- }
- // shader white border:
- else if ( !shader->IsDefault() ) {
- glColor3f( 1, 1, 1 );
- glDisable( GL_TEXTURE_2D );
- glBegin( GL_LINE_LOOP );
- glVertex2f( xfMin ,yfMax );
- glVertex2f( xfMin ,yfMin );
- glVertex2f( xfMax ,yfMin );
- glVertex2f( xfMax ,yfMax );
- glEnd();
- glEnable( GL_TEXTURE_2D );
- }
-
- // shader stipple:
- if ( !shader->IsDefault() ) {
- glEnable( GL_LINE_STIPPLE );
- glLineStipple( 1, 0xF000 );
- glDisable( GL_TEXTURE_2D );
- glBegin( GL_LINE_LOOP );
- glColor3f( 0, 0, 0 );
- glVertex2f( xfMin ,yfMax );
- glVertex2f( xfMin ,yfMin );
- glVertex2f( xfMax ,yfMin );
- glVertex2f( xfMax ,yfMax );
- glEnd();
- glDisable( GL_LINE_STIPPLE );
- glEnable( GL_TEXTURE_2D );
- }
-
- // draw checkerboard for transparent textures
- if ( g_TextureBrowser_enableAlpha )
- {
- glDisable( GL_TEXTURE_2D );
- glBegin( GL_QUADS );
- int font_height = TextureBrowser_fontHeight( textureBrowser );
- for ( int i = 0; i < nHeight; i += 8 )
- for ( int j = 0; j < nWidth; j += 8 )
- {
- unsigned char color = (i + j) / 8 % 2 ? 0x66 : 0x99;
- glColor3ub( color, color, color );
- int left = j;
- int right = std::min(j+8, nWidth);
- int top = i;
- int bottom = std::min(i+8, nHeight);
- glVertex2i(x + right, y - nHeight - font_height + top);
- glVertex2i(x + left, y - nHeight - font_height + top);
- glVertex2i(x + left, y - nHeight - font_height + bottom);
- glVertex2i(x + right, y - nHeight - font_height + bottom);
- }
- glEnd();
- glEnable( GL_TEXTURE_2D );
- }
-
- // Draw the texture
- glBindTexture( GL_TEXTURE_2D, q->texture_number );
- GlobalOpenGL_debugAssertNoErrors();
- glColor3f( 1,1,1 );
- glBegin( GL_QUADS );
- glTexCoord2i( 0,0 );
- glVertex2i( x,y - TextureBrowser_fontHeight( textureBrowser ) );
- glTexCoord2i( 1,0 );
- glVertex2i( x + nWidth,y - TextureBrowser_fontHeight( textureBrowser ) );
- glTexCoord2i( 1,1 );
- glVertex2i( x + nWidth,y - TextureBrowser_fontHeight( textureBrowser ) - nHeight );
- glTexCoord2i( 0,1 );
- glVertex2i( x,y - TextureBrowser_fontHeight( textureBrowser ) - nHeight );
- glEnd();
-
- // draw the texture name
- glDisable( GL_TEXTURE_2D );
- glColor3f( 1,1,1 );
-
- glRasterPos2i( x, y - TextureBrowser_fontHeight( textureBrowser ) + 2 );//+5
-
- // don't draw the directory name
- const char* name = shader->getName();
- name += strlen( name );
- while ( name != shader->getName() && *( name - 1 ) != '/' && *( name - 1 ) != '\\' )
- name--;
-
- GlobalOpenGL().drawString( name );
- glEnable( GL_TEXTURE_2D );
- }
-
- //int totalHeight = abs(y) + last_height + TextureBrowser_fontHeight(textureBrowser) + 4;
- }
-
-
- // reset the current texture
- glBindTexture( GL_TEXTURE_2D, 0 );
- //qglFinish();
-}
-
-void TextureBrowser_queueDraw( TextureBrowser& textureBrowser ){
- if ( textureBrowser.m_gl_widget ) {
- gtk_widget_queue_draw( textureBrowser.m_gl_widget );
- }
-}
-
-
-void TextureBrowser_setScale( TextureBrowser& textureBrowser, std::size_t scale ){
- textureBrowser.m_textureScale = scale;
-
- textureBrowser.m_heightChanged = true;
- textureBrowser.m_originInvalid = true;
- g_activeShadersChangedCallbacks();
-
- TextureBrowser_queueDraw( textureBrowser );
-}
-
-void TextureBrowser_setUniformSize( TextureBrowser& textureBrowser, std::size_t scale ){
- textureBrowser.m_uniformTextureSize = scale;
-
- textureBrowser.m_heightChanged = true;
- textureBrowser.m_originInvalid = true;
- g_activeShadersChangedCallbacks();
-
- TextureBrowser_queueDraw( textureBrowser );
-}
-
-void TextureBrowser_setUniformMinSize( TextureBrowser& textureBrowser, std::size_t scale ){
- textureBrowser.m_uniformTextureMinSize = scale;
-
- textureBrowser.m_heightChanged = true;
- textureBrowser.m_originInvalid = true;
- g_activeShadersChangedCallbacks();
-
- TextureBrowser_queueDraw( textureBrowser );
-}
-
-void TextureBrowser_MouseWheel( TextureBrowser& textureBrowser, bool bUp ){
- int originy = TextureBrowser_getOriginY( textureBrowser );
-
- if ( bUp ) {
- originy += int(textureBrowser.m_mouseWheelScrollIncrement);
- }
- else
- {
- originy -= int(textureBrowser.m_mouseWheelScrollIncrement);
- }
-
- TextureBrowser_setOriginY( textureBrowser, originy );
-}
-
-XmlTagBuilder TagBuilder;
-
-enum
-{
- TAG_COLUMN,
- N_COLUMNS
-};
-
-void BuildStoreAssignedTags( ui::ListStore store, const char* shader, TextureBrowser* textureBrowser ){
- GtkTreeIter iter;
-
- store.clear();
-
- std::vector<CopiedString> assigned_tags;
- TagBuilder.GetShaderTags( shader, assigned_tags );
-
- for ( size_t i = 0; i < assigned_tags.size(); i++ )
- {
- store.append(TAG_COLUMN, assigned_tags[i].c_str());
- }
-}
-
-void BuildStoreAvailableTags( ui::ListStore storeAvailable,
- ui::ListStore storeAssigned,
- const std::set<CopiedString>& allTags,
- TextureBrowser* textureBrowser ){
- GtkTreeIter iterAssigned;
- GtkTreeIter iterAvailable;
- std::set<CopiedString>::const_iterator iterAll;
- gchar* tag_assigned;
-
- storeAvailable.clear();
-
- bool row = gtk_tree_model_get_iter_first(storeAssigned, &iterAssigned ) != 0;
-
- if ( !row ) { // does the shader have tags assigned?
- for ( iterAll = allTags.begin(); iterAll != allTags.end(); ++iterAll )
- {
- storeAvailable.append(TAG_COLUMN, (*iterAll).c_str());
- }
- }
- else
- {
- while ( row ) // available tags = all tags - assigned tags
- {
- gtk_tree_model_get(storeAssigned, &iterAssigned, TAG_COLUMN, &tag_assigned, -1 );
-
- for ( iterAll = allTags.begin(); iterAll != allTags.end(); ++iterAll )
- {
- if ( strcmp( (char*)tag_assigned, ( *iterAll ).c_str() ) != 0 ) {
- storeAvailable.append(TAG_COLUMN, (*iterAll).c_str());
- }
- else
- {
- row = gtk_tree_model_iter_next(storeAssigned, &iterAssigned ) != 0;
-
- if ( row ) {
- gtk_tree_model_get(storeAssigned, &iterAssigned, TAG_COLUMN, &tag_assigned, -1 );
- }
- }
- }
- }
- }
-}
-
-gboolean TextureBrowser_button_press( ui::Widget widget, GdkEventButton* event, TextureBrowser* textureBrowser ){
- if ( event->type == GDK_BUTTON_PRESS ) {
- if ( event->button == 3 ) {
- if ( GlobalTextureBrowser().m_tags ) {
- textureBrowser->m_rmbSelected = true;
- TextureBrowser_Selection_MouseDown( *textureBrowser, event->state, static_cast<int>( event->x ), static_cast<int>( event->y ) );
-
- BuildStoreAssignedTags( textureBrowser->m_assigned_store, textureBrowser->shader.c_str(), textureBrowser );
- BuildStoreAvailableTags( textureBrowser->m_available_store, textureBrowser->m_assigned_store, textureBrowser->m_all_tags, textureBrowser );
- textureBrowser->m_heightChanged = true;
- textureBrowser->m_tag_frame.show();
-
- ui::process();
-
- TextureBrowser_Focus( *textureBrowser, textureBrowser->shader.c_str() );
- }
- else
- {
- TextureBrowser_Tracking_MouseDown( *textureBrowser );
- }
- }
- else if ( event->button == 1 ) {
- TextureBrowser_Selection_MouseDown( *textureBrowser, event->state, static_cast<int>( event->x ), static_cast<int>( event->y ) );
-
- if ( GlobalTextureBrowser().m_tags ) {
- textureBrowser->m_rmbSelected = false;
- textureBrowser->m_tag_frame.hide();
- }
- }
- }
- else if ( event->type == GDK_2BUTTON_PRESS && event->button == 1 ) {
- #define GARUX_DISABLE_2BUTTON
- #ifndef GARUX_DISABLE_2BUTTON
- CopiedString texName = textureBrowser->shader;
- //const char* sh = texName.c_str();
- char* sh = const_cast<char*>( texName.c_str() );
- char* dir = strrchr( sh, '/' );
- if( dir != NULL ){
- *(dir + 1) = '\0';
- dir = strchr( sh, '/' );
- if( dir != NULL ){
- dir++;
- if( *dir != '\0'){
- ScopeDisableScreenUpdates disableScreenUpdates( dir, "Loading Textures" );
- TextureBrowser_ShowDirectory( *textureBrowser, dir );
- TextureBrowser_Focus( *textureBrowser, textureBrowser->shader.c_str() );
- TextureBrowser_queueDraw( *textureBrowser );
- }
- }
- }
- #endif
- }
- else if ( event->type == GDK_2BUTTON_PRESS && event->button == 3 ) {
- ScopeDisableScreenUpdates disableScreenUpdates( TextureBrowser_getComonShadersDir(), "Loading Textures" );
- TextureBrowser_ShowDirectory( *textureBrowser, TextureBrowser_getComonShadersDir() );
- TextureBrowser_queueDraw( *textureBrowser );
- }
- return FALSE;
-}
-
-gboolean TextureBrowser_button_release( ui::Widget widget, GdkEventButton* event, TextureBrowser* textureBrowser ){
- if ( event->type == GDK_BUTTON_RELEASE ) {
- if ( event->button == 3 ) {
- if ( !GlobalTextureBrowser().m_tags ) {
- TextureBrowser_Tracking_MouseUp( *textureBrowser );
- }
- }
- }
- return FALSE;
-}
-
-gboolean TextureBrowser_motion( ui::Widget widget, GdkEventMotion *event, TextureBrowser* textureBrowser ){
- return FALSE;
-}
-
-gboolean TextureBrowser_scroll( ui::Widget widget, GdkEventScroll* event, TextureBrowser* textureBrowser ){
- if ( event->direction == GDK_SCROLL_UP ) {
- TextureBrowser_MouseWheel( *textureBrowser, true );
- }
- else if ( event->direction == GDK_SCROLL_DOWN ) {
- TextureBrowser_MouseWheel( *textureBrowser, false );
- }
- return FALSE;
-}
-
-void TextureBrowser_scrollChanged( void* data, gdouble value ){
- //globalOutputStream() << "vertical scroll\n";
- TextureBrowser_setOriginY( *reinterpret_cast<TextureBrowser*>( data ), -(int)value );
-}
-
-static void TextureBrowser_verticalScroll(ui::Adjustment adjustment, TextureBrowser* textureBrowser ){
- textureBrowser->m_scrollAdjustment.value_changed( gtk_adjustment_get_value(adjustment) );
-}
-
-void TextureBrowser_updateScroll( TextureBrowser& textureBrowser ){
- if ( textureBrowser.m_showTextureScrollbar ) {
- int totalHeight = TextureBrowser_TotalHeight( textureBrowser );
-
- totalHeight = std::max( totalHeight, textureBrowser.height );
-
- auto vadjustment = gtk_range_get_adjustment( GTK_RANGE( textureBrowser.m_texture_scroll ) );
-
- gtk_adjustment_set_value(vadjustment, -TextureBrowser_getOriginY( textureBrowser ));
- gtk_adjustment_set_page_size(vadjustment, textureBrowser.height);
- gtk_adjustment_set_page_increment(vadjustment, textureBrowser.height / 2);
- gtk_adjustment_set_step_increment(vadjustment, 20);
- gtk_adjustment_set_lower(vadjustment, 0);
- gtk_adjustment_set_upper(vadjustment, totalHeight);
-
- g_signal_emit_by_name( G_OBJECT( vadjustment ), "changed" );
- }
-}
-
-gboolean TextureBrowser_size_allocate( ui::Widget widget, GtkAllocation* allocation, TextureBrowser* textureBrowser ){
- textureBrowser->width = allocation->width;
- textureBrowser->height = allocation->height;
- TextureBrowser_heightChanged( *textureBrowser );
- textureBrowser->m_originInvalid = true;
- TextureBrowser_queueDraw( *textureBrowser );
- return FALSE;
-}
-
-gboolean TextureBrowser_expose( ui::Widget widget, GdkEventExpose* event, TextureBrowser* textureBrowser ){
- if ( glwidget_make_current( textureBrowser->m_gl_widget ) != FALSE ) {
- GlobalOpenGL_debugAssertNoErrors();
- TextureBrowser_evaluateHeight( *textureBrowser );
- Texture_Draw( *textureBrowser );
- GlobalOpenGL_debugAssertNoErrors();
- glwidget_swap_buffers( textureBrowser->m_gl_widget );
- }
- return FALSE;
-}
-
-
-TextureBrowser g_TextureBrowser;
-
-TextureBrowser& GlobalTextureBrowser(){
- return g_TextureBrowser;
-}
-
-bool TextureBrowser_hideUnused(){
- return g_TextureBrowser.m_hideUnused;
-}
-
-void TextureBrowser_ToggleHideUnused(){
- if ( g_TextureBrowser.m_hideUnused ) {
- TextureBrowser_SetHideUnused( g_TextureBrowser, false );
- }
- else
- {
- TextureBrowser_SetHideUnused( g_TextureBrowser, true );
- }
-}
-
-void TextureGroups_constructTreeModel( TextureGroups groups, ui::TreeStore store ){
- // put the information from the old textures menu into a treeview
- GtkTreeIter iter, child;
-
- TextureGroups::const_iterator i = groups.begin();
- while ( i != groups.end() )
- {
- const char* dirName = ( *i ).c_str();
- const char* firstUnderscore = strchr( dirName, '_' );
- StringRange dirRoot( dirName, ( firstUnderscore == 0 ) ? dirName : firstUnderscore + 1 );
-
- TextureGroups::const_iterator next = i;
- ++next;
- if ( firstUnderscore != 0
- && next != groups.end()
- && string_equal_start( ( *next ).c_str(), dirRoot ) ) {
- gtk_tree_store_append( store, &iter, NULL );
- gtk_tree_store_set( store, &iter, 0, CopiedString( StringRange( dirName, firstUnderscore ) ).c_str(), -1 );
-
- // keep going...
- while ( i != groups.end() && string_equal_start( ( *i ).c_str(), dirRoot ) )
- {
- gtk_tree_store_append( store, &child, &iter );
- gtk_tree_store_set( store, &child, 0, ( *i ).c_str(), -1 );
- ++i;
- }
- }
- else
- {
- gtk_tree_store_append( store, &iter, NULL );
- gtk_tree_store_set( store, &iter, 0, dirName, -1 );
- ++i;
- }
- }
-}
-
-TextureGroups TextureGroups_constructTreeView(){
- TextureGroups groups;
-
- if ( TextureBrowser_showWads() ) {
- GlobalFileSystem().forEachArchive( TextureGroupsAddWadCaller( groups ) );
- }
- else
- {
- // scan texture dirs and pak files only if not restricting to shaderlist
- if ( g_pGameDescription->mGameType != "doom3" && !g_TextureBrowser_shaderlistOnly ) {
- GlobalFileSystem().forEachDirectory( "textures/", TextureGroupsAddDirectoryCaller( groups ) );
- }
-
- GlobalShaderSystem().foreachShaderName( TextureGroupsAddShaderCaller( groups ) );
- }
-
- return groups;
-}
-
-void TextureBrowser_constructTreeStore(){
- TextureGroups groups = TextureGroups_constructTreeView();
- auto store = ui::TreeStore::from(gtk_tree_store_new( 1, G_TYPE_STRING ));
- TextureGroups_constructTreeModel( groups, store );
- std::set<CopiedString>::iterator iter;
-
- gtk_tree_view_set_model(g_TextureBrowser.m_treeViewTree, store);
-
- g_object_unref( G_OBJECT( store ) );
-}
-
-void TextureBrowser_constructTreeStoreTags(){
- //TextureGroups groups;
- auto store = ui::TreeStore::from(gtk_tree_store_new( 1, G_TYPE_STRING ));
- auto model = g_TextureBrowser.m_all_tags_list;
-
- gtk_tree_view_set_model(g_TextureBrowser.m_treeViewTags, model );
-
- g_object_unref( G_OBJECT( store ) );
-}
-
-void TreeView_onRowActivated( ui::TreeView treeview, ui::TreePath path, ui::TreeViewColumn col, gpointer userdata ){
- GtkTreeIter iter;
-
- auto model = gtk_tree_view_get_model(treeview );
-
- if ( gtk_tree_model_get_iter( model, &iter, path ) ) {
- gchar dirName[1024];
-
- gchar* buffer;
- gtk_tree_model_get( model, &iter, 0, &buffer, -1 );
- strcpy( dirName, buffer );
- g_free( buffer );
-
- g_TextureBrowser.m_searchedTags = false;
-
- if ( !TextureBrowser_showWads() ) {
- strcat( dirName, "/" );
- }
-
- ScopeDisableScreenUpdates disableScreenUpdates( dirName, "Loading Textures" );
- TextureBrowser_ShowDirectory( GlobalTextureBrowser(), dirName );
- TextureBrowser_queueDraw( GlobalTextureBrowser() );
- //deactivate, so SPACE and RETURN wont be broken for 2d
- gtk_window_set_focus( GTK_WINDOW( gtk_widget_get_toplevel( GTK_WIDGET( treeview ) ) ), NULL );
- }
-}
-
-void TextureBrowser_createTreeViewTree(){
- gtk_tree_view_set_enable_search(g_TextureBrowser.m_treeViewTree, FALSE );
-
- gtk_tree_view_set_headers_visible(g_TextureBrowser.m_treeViewTree, FALSE );
- g_TextureBrowser.m_treeViewTree.connect( "row-activated", (GCallback) TreeView_onRowActivated, NULL );
-
- auto renderer = ui::CellRendererText(ui::New);
- gtk_tree_view_insert_column_with_attributes(g_TextureBrowser.m_treeViewTree, -1, "", renderer, "text", 0, NULL );
-
- TextureBrowser_constructTreeStore();
-}
-
-void TextureBrowser_addTag();
-
-void TextureBrowser_renameTag();
-
-void TextureBrowser_deleteTag();
-
-void TextureBrowser_createContextMenu( ui::Widget treeview, GdkEventButton *event ){
- ui::Widget menu = ui::Menu(ui::New);
-
- ui::Widget menuitem = ui::MenuItem( "Add tag" );
- menuitem.connect( "activate", (GCallback)TextureBrowser_addTag, treeview );
- gtk_menu_shell_append( GTK_MENU_SHELL( menu ), menuitem );
-
- menuitem = ui::MenuItem( "Rename tag" );
- menuitem.connect( "activate", (GCallback)TextureBrowser_renameTag, treeview );
- gtk_menu_shell_append( GTK_MENU_SHELL( menu ), menuitem );
-
- menuitem = ui::MenuItem( "Delete tag" );
- menuitem.connect( "activate", (GCallback)TextureBrowser_deleteTag, treeview );
- gtk_menu_shell_append( GTK_MENU_SHELL( menu ), menuitem );
-
- gtk_widget_show_all( menu );
-
- gtk_menu_popup( GTK_MENU( menu ), NULL, NULL, NULL, NULL,
- ( event != NULL ) ? event->button : 0,
- gdk_event_get_time( (GdkEvent*)event ) );
-}
-
-gboolean TreeViewTags_onButtonPressed( ui::TreeView treeview, GdkEventButton *event ){
- if ( event->type == GDK_BUTTON_PRESS && event->button == 3 ) {
- GtkTreePath *path;
- auto selection = gtk_tree_view_get_selection(treeview );
-
- if ( gtk_tree_view_get_path_at_pos(treeview, event->x, event->y, &path, NULL, NULL, NULL ) ) {
- gtk_tree_selection_unselect_all( selection );
- gtk_tree_selection_select_path( selection, path );
- gtk_tree_path_free( path );
- }
-
- TextureBrowser_createContextMenu( treeview, event );
- return TRUE;
- }
- return FALSE;
-}
-
-void TextureBrowser_createTreeViewTags(){
- g_TextureBrowser.m_treeViewTags = ui::TreeView(ui::New);
- gtk_tree_view_set_enable_search(g_TextureBrowser.m_treeViewTags, FALSE );
-
- g_TextureBrowser.m_treeViewTags.connect( "button-press-event", (GCallback)TreeViewTags_onButtonPressed, NULL );
-
- gtk_tree_view_set_headers_visible(g_TextureBrowser.m_treeViewTags, FALSE );
-
- auto renderer = ui::CellRendererText(ui::New);
- gtk_tree_view_insert_column_with_attributes(g_TextureBrowser.m_treeViewTags, -1, "", renderer, "text", 0, NULL );
-
- TextureBrowser_constructTreeStoreTags();
-}
-
-ui::MenuItem TextureBrowser_constructViewMenu( ui::Menu menu ){
- ui::MenuItem textures_menu_item = ui::MenuItem(new_sub_menu_item_with_mnemonic( "_View" ));
-
- if ( g_Layout_enableDetachableMenus.m_value ) {
- menu_tearoff( menu );
- }
-
- create_check_menu_item_with_mnemonic( menu, "Hide _Unused", "ShowInUse" );
- if ( string_empty( g_pGameDescription->getKeyValue( "show_wads" ) ) ) {
- create_check_menu_item_with_mnemonic( menu, "Hide Image Missing", "FilterMissing" );
- }
-
- // hide notex and shadernotex on texture browser: no one wants to apply them
- create_check_menu_item_with_mnemonic( menu, "Hide Fallback", "FilterFallback" );
-
- menu_separator( menu );
-
-
- // we always want to show shaders but don't want a "Show Shaders" menu for doom3 and .wad file games
- if ( g_pGameDescription->mGameType == "doom3" || !string_empty( g_pGameDescription->getKeyValue( "show_wads" ) ) ) {
- g_TextureBrowser.m_showShaders = true;
- }
- else
- {
- create_check_menu_item_with_mnemonic( menu, "Show shaders", "ToggleShowShaders" );
- create_check_menu_item_with_mnemonic( menu, "Show textures", "ToggleShowTextures" );
- menu_separator( menu );
- }
-
- if ( g_TextureBrowser.m_tags ) {
- create_menu_item_with_mnemonic( menu, "Show Untagged", "ShowUntagged" );
- }
- if ( g_pGameDescription->mGameType != "doom3" && string_empty( g_pGameDescription->getKeyValue( "show_wads" ) ) ) {
- create_check_menu_item_with_mnemonic( menu, "ShaderList Only", "ToggleShowShaderlistOnly" );
- }
-
- menu_separator( menu );
- create_check_menu_item_with_mnemonic( menu, "Fixed Size", "FixedSize" );
- create_check_menu_item_with_mnemonic( menu, "Transparency", "EnableAlpha" );
-
- if ( string_empty( g_pGameDescription->getKeyValue( "show_wads" ) ) ) {
- menu_separator( menu );
- g_TextureBrowser.m_shader_info_item = ui::Widget(create_menu_item_with_mnemonic( menu, "Shader Info", "ShaderInfo" ));
- gtk_widget_set_sensitive( g_TextureBrowser.m_shader_info_item, FALSE );
- }
-
-
- return textures_menu_item;
-}
-
-void Popup_View_Menu( GtkWidget *widget, GtkMenu *menu ){
- gtk_menu_popup( menu, NULL, NULL, NULL, NULL, 1, gtk_get_current_event_time() );
-}
-
-ui::MenuItem TextureBrowser_constructToolsMenu( ui::Menu menu ){
- ui::MenuItem textures_menu_item = ui::MenuItem(new_sub_menu_item_with_mnemonic( "_Tools" ));
-
- if ( g_Layout_enableDetachableMenus.m_value ) {
- menu_tearoff( menu );
- }
-
- create_menu_item_with_mnemonic( menu, "Flush & Reload Shaders", "RefreshShaders" );
- create_menu_item_with_mnemonic( menu, "Find / Replace...", "FindReplaceTextures" );
-
- return textures_menu_item;
-}
-
-ui::MenuItem TextureBrowser_constructTagsMenu( ui::Menu menu ){
- ui::MenuItem textures_menu_item = ui::MenuItem(new_sub_menu_item_with_mnemonic( "T_ags" ));
-
- if ( g_Layout_enableDetachableMenus.m_value ) {
- menu_tearoff( menu );
- }
-
- create_menu_item_with_mnemonic( menu, "Add tag", "AddTag" );
- create_menu_item_with_mnemonic( menu, "Rename tag", "RenameTag" );
- create_menu_item_with_mnemonic( menu, "Delete tag", "DeleteTag" );
- menu_separator( menu );
- create_menu_item_with_mnemonic( menu, "Copy tags from selected", "CopyTag" );
- create_menu_item_with_mnemonic( menu, "Paste tags to selected", "PasteTag" );
-
- return textures_menu_item;
-}
-
-gboolean TextureBrowser_tagMoveHelper( ui::TreeModel model, ui::TreePath path, GtkTreeIter iter, GSList** selected ){
- g_assert( selected != NULL );
-
- auto rowref = gtk_tree_row_reference_new( model, path );
- *selected = g_slist_append( *selected, rowref );
-
- return FALSE;
-}
-
-void TextureBrowser_assignTags(){
- GSList* selected = NULL;
- GSList* node;
- gchar* tag_assigned;
-
- auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_available_tree );
-
- gtk_tree_selection_selected_foreach( selection, (GtkTreeSelectionForeachFunc)TextureBrowser_tagMoveHelper, &selected );
-
- if ( selected != NULL ) {
- for ( node = selected; node != NULL; node = node->next )
- {
- auto path = gtk_tree_row_reference_get_path( (GtkTreeRowReference*)node->data );
-
- if ( path ) {
- GtkTreeIter iter;
-
- if ( gtk_tree_model_get_iter(g_TextureBrowser.m_available_store, &iter, path ) ) {
- gtk_tree_model_get(g_TextureBrowser.m_available_store, &iter, TAG_COLUMN, &tag_assigned, -1 );
- if ( !TagBuilder.CheckShaderTag( g_TextureBrowser.shader.c_str() ) ) {
- // create a custom shader/texture entry
- IShader* ishader = QERApp_Shader_ForName( g_TextureBrowser.shader.c_str() );
- CopiedString filename = ishader->getShaderFileName();
-
- if ( filename.empty() ) {
- // it's a texture
- TagBuilder.AddShaderNode( g_TextureBrowser.shader.c_str(), CUSTOM, TEXTURE );
- }
- else {
- // it's a shader
- TagBuilder.AddShaderNode( g_TextureBrowser.shader.c_str(), CUSTOM, SHADER );
- }
- ishader->DecRef();
- }
- TagBuilder.AddShaderTag( g_TextureBrowser.shader.c_str(), (char*)tag_assigned, TAG );
-
- gtk_list_store_remove( g_TextureBrowser.m_available_store, &iter );
- g_TextureBrowser.m_assigned_store.append(TAG_COLUMN, tag_assigned);
- }
- }
- }
-
- g_slist_foreach( selected, (GFunc)gtk_tree_row_reference_free, NULL );
-
- // Save changes
- TagBuilder.SaveXmlDoc();
- }
- g_slist_free( selected );
-}
-
-void TextureBrowser_removeTags(){
- GSList* selected = NULL;
- GSList* node;
- gchar* tag;
-
- auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_assigned_tree );
-
- gtk_tree_selection_selected_foreach( selection, (GtkTreeSelectionForeachFunc)TextureBrowser_tagMoveHelper, &selected );
-
- if ( selected != NULL ) {
- for ( node = selected; node != NULL; node = node->next )
- {
- auto path = gtk_tree_row_reference_get_path( (GtkTreeRowReference*)node->data );
-
- if ( path ) {
- GtkTreeIter iter;
-
- if ( gtk_tree_model_get_iter(g_TextureBrowser.m_assigned_store, &iter, path ) ) {
- gtk_tree_model_get(g_TextureBrowser.m_assigned_store, &iter, TAG_COLUMN, &tag, -1 );
- TagBuilder.DeleteShaderTag( g_TextureBrowser.shader.c_str(), tag );
- gtk_list_store_remove( g_TextureBrowser.m_assigned_store, &iter );
- }
- }
- }
-
- g_slist_foreach( selected, (GFunc)gtk_tree_row_reference_free, NULL );
-
- // Update the "available tags list"
- BuildStoreAvailableTags( g_TextureBrowser.m_available_store, g_TextureBrowser.m_assigned_store, g_TextureBrowser.m_all_tags, &g_TextureBrowser );
-
- // Save changes
- TagBuilder.SaveXmlDoc();
- }
- g_slist_free( selected );
-}
-
-void TextureBrowser_buildTagList(){
- g_TextureBrowser.m_all_tags_list.clear();
-
- std::set<CopiedString>::iterator iter;
-
- for ( iter = g_TextureBrowser.m_all_tags.begin(); iter != g_TextureBrowser.m_all_tags.end(); ++iter )
- {
- g_TextureBrowser.m_all_tags_list.append(TAG_COLUMN, (*iter).c_str());
- }
-}
-
-void TextureBrowser_searchTags(){
- GSList* selected = NULL;
- GSList* node;
- gchar* tag;
- char buffer[256];
- char tags_searched[256];
-
- auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_treeViewTags );
-
- gtk_tree_selection_selected_foreach( selection, (GtkTreeSelectionForeachFunc)TextureBrowser_tagMoveHelper, &selected );
-
- if ( selected != NULL ) {
- strcpy( buffer, "/root/*/*[tag='" );
- strcpy( tags_searched, "[TAGS] " );
-
- for ( node = selected; node != NULL; node = node->next )
- {
- auto path = gtk_tree_row_reference_get_path( (GtkTreeRowReference*)node->data );
-
- if ( path ) {
- GtkTreeIter iter;
-
- if ( gtk_tree_model_get_iter(g_TextureBrowser.m_all_tags_list, &iter, path ) ) {
- gtk_tree_model_get(g_TextureBrowser.m_all_tags_list, &iter, TAG_COLUMN, &tag, -1 );
-
- strcat( buffer, tag );
- strcat( tags_searched, tag );
- if ( node != g_slist_last( node ) ) {
- strcat( buffer, "' and tag='" );
- strcat( tags_searched, ", " );
- }
- }
- }
- }
-
- strcat( buffer, "']" );
-
- g_slist_foreach( selected, (GFunc)gtk_tree_row_reference_free, NULL );
-
- g_TextureBrowser.m_found_shaders.clear(); // delete old list
- TagBuilder.TagSearch( buffer, g_TextureBrowser.m_found_shaders );
-
- if ( !g_TextureBrowser.m_found_shaders.empty() ) { // found something
- size_t shaders_found = g_TextureBrowser.m_found_shaders.size();
-
- globalOutputStream() << "Found " << (unsigned int)shaders_found << " textures and shaders with " << tags_searched << "\n";
- ScopeDisableScreenUpdates disableScreenUpdates( "Searching...", "Loading Textures" );
-
- std::set<CopiedString>::iterator iter;
-
- for ( iter = g_TextureBrowser.m_found_shaders.begin(); iter != g_TextureBrowser.m_found_shaders.end(); iter++ )
- {
- std::string path = ( *iter ).c_str();
- size_t pos = path.find_last_of( "/", path.size() );
- std::string name = path.substr( pos + 1, path.size() );
- path = path.substr( 0, pos + 1 );
- TextureDirectory_loadTexture( path.c_str(), name.c_str() );
- }
- }
- g_TextureBrowser.m_searchedTags = true;
- g_TextureBrowser_currentDirectory = tags_searched;
-
- g_TextureBrowser.m_nTotalHeight = 0;
- TextureBrowser_setOriginY( g_TextureBrowser, 0 );
- TextureBrowser_heightChanged( g_TextureBrowser );
- TextureBrowser_updateTitle();
- }
- g_slist_free( selected );
-}
-
-void TextureBrowser_toggleSearchButton(){
- gint page = gtk_notebook_get_current_page( GTK_NOTEBOOK( g_TextureBrowser.m_tag_notebook ) );
-
- if ( page == 0 ) { // tag page
- gtk_widget_show_all( g_TextureBrowser.m_search_button );
- }
- else {
- g_TextureBrowser.m_search_button.hide();
- }
-}
-
-void TextureBrowser_constructTagNotebook(){
- g_TextureBrowser.m_tag_notebook = ui::Widget::from(gtk_notebook_new());
- ui::Widget labelTags = ui::Label( "Tags" );
- ui::Widget labelTextures = ui::Label( "Textures" );
-
- gtk_notebook_append_page( GTK_NOTEBOOK( g_TextureBrowser.m_tag_notebook ), g_TextureBrowser.m_scr_win_tree, labelTextures );
- gtk_notebook_append_page( GTK_NOTEBOOK( g_TextureBrowser.m_tag_notebook ), g_TextureBrowser.m_scr_win_tags, labelTags );
-
- g_TextureBrowser.m_tag_notebook.connect( "switch-page", G_CALLBACK( TextureBrowser_toggleSearchButton ), NULL );
-
- gtk_widget_show_all( g_TextureBrowser.m_tag_notebook );
-}
-
-void TextureBrowser_constructSearchButton(){
- auto image = ui::Widget::from(gtk_image_new_from_stock( GTK_STOCK_FIND, GTK_ICON_SIZE_SMALL_TOOLBAR ));
- g_TextureBrowser.m_search_button = ui::Button(ui::New);
- g_TextureBrowser.m_search_button.connect( "clicked", G_CALLBACK( TextureBrowser_searchTags ), NULL );
- gtk_widget_set_tooltip_text(g_TextureBrowser.m_search_button, "Search with selected tags");
- g_TextureBrowser.m_search_button.add(image);
-}
-
-void TextureBrowser_checkTagFile(){
- const char SHADERTAG_FILE[] = "shadertags.xml";
- CopiedString default_filename, rc_filename;
- StringOutputStream stream( 256 );
-
- stream << LocalRcPath_get();
- stream << SHADERTAG_FILE;
- rc_filename = stream.c_str();
-
- if ( file_exists( rc_filename.c_str() ) ) {
- g_TextureBrowser.m_tags = TagBuilder.OpenXmlDoc( rc_filename.c_str() );
-
- if ( g_TextureBrowser.m_tags ) {
- globalOutputStream() << "Loading tag file " << rc_filename.c_str() << ".\n";
- }
- }
- else
- {
- // load default tagfile
- stream.clear();
- stream << g_pGameDescription->mGameToolsPath.c_str();
- stream << SHADERTAG_FILE;
- default_filename = stream.c_str();
-
- if ( file_exists( default_filename.c_str() ) ) {
- g_TextureBrowser.m_tags = TagBuilder.OpenXmlDoc( default_filename.c_str(), rc_filename.c_str() );
-
- if ( g_TextureBrowser.m_tags ) {
- globalOutputStream() << "Loading default tag file " << default_filename.c_str() << ".\n";
- }
- }
- else
- {
- globalOutputStream() << "Unable to find default tag file " << default_filename.c_str() << ". No tag support. Plugins -> ShaderPlug -> Create tag file: to start using tags\n";
- }
- }
-}
-
-void TextureBrowser_SetNotex(){
- IShader* notex = QERApp_Shader_ForName( DEFAULT_NOTEX_NAME );
- IShader* shadernotex = QERApp_Shader_ForName( DEFAULT_SHADERNOTEX_NAME );
-
- g_notex = notex->getTexture()->name;
- g_shadernotex = shadernotex->getTexture()->name;
-
- notex->DecRef();
- shadernotex->DecRef();
-}
-
-ui::Widget TextureBrowser_constructWindow( ui::Window toplevel ){
- // The gl_widget and the tag assignment frame should be packed into a GtkVPaned with the slider
- // position stored in local.pref. gtk_paned_get_position() and gtk_paned_set_position() don't
- // seem to work in gtk 2.4 and the arrow buttons don't handle GTK_FILL, so here's another thing
- // for the "once-the-gtk-libs-are-updated-TODO-list" :x
-
- TextureBrowser_checkTagFile();
- TextureBrowser_SetNotex();
-
- GlobalShaderSystem().setActiveShadersChangedNotify( ReferenceCaller<TextureBrowser, void(), TextureBrowser_activeShadersChanged>( g_TextureBrowser ) );
-
- g_TextureBrowser.m_parent = toplevel;
-
- auto table = ui::Table(3, 3, FALSE);
- auto vbox = ui::VBox(FALSE, 0);
- table.attach(vbox, {0, 1, 1, 3}, {GTK_FILL, GTK_FILL});
- vbox.show();
-
- // ui::Widget menu_bar{ui::null};
- auto toolbar = ui::Toolbar::from( gtk_toolbar_new() );
-
- { // menu bar
- // menu_bar = ui::Widget::from(gtk_menu_bar_new());
- auto menu_view = ui::Menu(ui::New);
- // auto view_item = TextureBrowser_constructViewMenu( menu_view );
- TextureBrowser_constructViewMenu( menu_view );
- gtk_menu_set_title( menu_view, "View" );
- // gtk_menu_item_set_submenu( GTK_MENU_ITEM( view_item ), menu_view );
- // gtk_menu_shell_append( GTK_MENU_SHELL( menu_bar ), view_item );
-
- //gtk_table_attach( GTK_TABLE( table ), GTK_WIDGET( toolbar ), 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0 );
- gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( toolbar ), FALSE, FALSE, 0 );
-
- //view menu button
- {
- auto button = toolbar_append_button( toolbar, "View", "texbro_view.png" );
- button.dimensions( 22, 22 );
- button.connect( "clicked", G_CALLBACK( Popup_View_Menu ), menu_view );
-
- //to show detached menu over floating tex bro
- gtk_menu_attach_to_widget( GTK_MENU( menu_view ), GTK_WIDGET( button ), NULL );
- }
- {
- auto button = toolbar_append_button( toolbar, "Find / Replace...", "texbro_gtk-find-and-replace.png", "FindReplaceTextures" );
- button.dimensions( 22, 22 );
- }
- {
- auto button = toolbar_append_button( toolbar, "Flush & Reload Shaders", "texbro_refresh.png", "RefreshShaders" );
- button.dimensions( 22, 22 );
- }
- toolbar.show();
-
-/*
- auto menu_tools = ui::Menu(ui::New);
- auto tools_item = TextureBrowser_constructToolsMenu( menu_tools );
- gtk_menu_item_set_submenu( GTK_MENU_ITEM( tools_item ), menu_tools );
- gtk_menu_shell_append( GTK_MENU_SHELL( menu_bar ), tools_item );
-*/
- // table.attach(menu_bar, {0, 3, 0, 1}, {GTK_FILL, GTK_SHRINK});
- // menu_bar.show();
- }
- { // Texture TreeView
- g_TextureBrowser.m_scr_win_tree = ui::ScrolledWindow(ui::New);
- gtk_container_set_border_width( GTK_CONTAINER( g_TextureBrowser.m_scr_win_tree ), 0 );
-
- // vertical only scrolling for treeview
- gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( g_TextureBrowser.m_scr_win_tree ), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS );
-
- g_TextureBrowser.m_scr_win_tree.show();
-
- TextureBrowser_createTreeViewTree();
-
- gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( g_TextureBrowser.m_scr_win_tree ), g_TextureBrowser.m_treeViewTree );
- g_TextureBrowser.m_treeViewTree.show();
- }
- { // gl_widget scrollbar
- auto w = ui::Widget::from(gtk_vscrollbar_new( ui::Adjustment( 0,0,0,1,1,0 ) ));
- table.attach(w, {2, 3, 1, 2}, {GTK_SHRINK, GTK_FILL});
- w.show();
- g_TextureBrowser.m_texture_scroll = w;
-
- auto vadjustment = ui::Adjustment::from(gtk_range_get_adjustment( GTK_RANGE( g_TextureBrowser.m_texture_scroll ) ));
- vadjustment.connect( "value_changed", G_CALLBACK( TextureBrowser_verticalScroll ), &g_TextureBrowser );
-
- g_TextureBrowser.m_texture_scroll.visible(g_TextureBrowser.m_showTextureScrollbar);
- }
- { // gl_widget
- g_TextureBrowser.m_gl_widget = glwidget_new( FALSE );
- g_object_ref( g_TextureBrowser.m_gl_widget._handle );
-
- gtk_widget_set_events( g_TextureBrowser.m_gl_widget, GDK_DESTROY | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK );
- gtk_widget_set_can_focus( g_TextureBrowser.m_gl_widget, true );
-
- table.attach(g_TextureBrowser.m_gl_widget, {1, 2, 1, 2});
- g_TextureBrowser.m_gl_widget.show();
-
- g_TextureBrowser.m_sizeHandler = g_TextureBrowser.m_gl_widget.connect( "size_allocate", G_CALLBACK( TextureBrowser_size_allocate ), &g_TextureBrowser );
- g_TextureBrowser.m_exposeHandler = g_TextureBrowser.m_gl_widget.on_render( G_CALLBACK( TextureBrowser_expose ), &g_TextureBrowser );
-
- g_TextureBrowser.m_gl_widget.connect( "button_press_event", G_CALLBACK( TextureBrowser_button_press ), &g_TextureBrowser );
- g_TextureBrowser.m_gl_widget.connect( "button_release_event", G_CALLBACK( TextureBrowser_button_release ), &g_TextureBrowser );
- g_TextureBrowser.m_gl_widget.connect( "motion_notify_event", G_CALLBACK( TextureBrowser_motion ), &g_TextureBrowser );
- g_TextureBrowser.m_gl_widget.connect( "scroll_event", G_CALLBACK( TextureBrowser_scroll ), &g_TextureBrowser );
- }
-
- // tag stuff
- if ( g_TextureBrowser.m_tags ) {
- { // fill tag GtkListStore
- g_TextureBrowser.m_all_tags_list = ui::ListStore::from(gtk_list_store_new( N_COLUMNS, G_TYPE_STRING ));
- auto sortable = GTK_TREE_SORTABLE( g_TextureBrowser.m_all_tags_list );
- gtk_tree_sortable_set_sort_column_id( sortable, TAG_COLUMN, GTK_SORT_ASCENDING );
-
- TagBuilder.GetAllTags( g_TextureBrowser.m_all_tags );
- TextureBrowser_buildTagList();
- }
- { // tag menu bar
- auto menu_tags = ui::Menu(ui::New);
- // auto tags_item = TextureBrowser_constructTagsMenu( menu_tags );
- TextureBrowser_constructTagsMenu( menu_tags );
- // gtk_menu_item_set_submenu( GTK_MENU_ITEM( tags_item ), menu_tags );
- // gtk_menu_shell_append( GTK_MENU_SHELL( menu_bar ), tags_item );
-
- auto button = toolbar_append_button( toolbar, "Tags", "texbro_tags.png" );
- button.dimensions( 22, 22 );
- button.connect( "clicked", G_CALLBACK( Popup_View_Menu ), menu_tags );
- }
- { // Tag TreeView
- g_TextureBrowser.m_scr_win_tags = ui::ScrolledWindow(ui::New);
- gtk_container_set_border_width( GTK_CONTAINER( g_TextureBrowser.m_scr_win_tags ), 0 );
-
- // vertical only scrolling for treeview
- gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( g_TextureBrowser.m_scr_win_tags ), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS );
-
- TextureBrowser_createTreeViewTags();
-
- auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_treeViewTags );
- gtk_tree_selection_set_mode( selection, GTK_SELECTION_MULTIPLE );
-
- gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( g_TextureBrowser.m_scr_win_tags ), g_TextureBrowser.m_treeViewTags );
- g_TextureBrowser.m_treeViewTags.show();
- }
- { // Texture/Tag notebook
- TextureBrowser_constructTagNotebook();
- vbox.pack_start( g_TextureBrowser.m_tag_notebook, TRUE, TRUE, 0 );
- }
- { // Tag search button
- TextureBrowser_constructSearchButton();
- vbox.pack_end(g_TextureBrowser.m_search_button, FALSE, FALSE, 0);
- }
- auto frame_table = ui::Table(3, 3, FALSE);
- { // Tag frame
-
- g_TextureBrowser.m_tag_frame = ui::Frame( "Tag assignment" );
- gtk_frame_set_label_align( GTK_FRAME( g_TextureBrowser.m_tag_frame ), 0.5, 0.5 );
- gtk_frame_set_shadow_type( GTK_FRAME( g_TextureBrowser.m_tag_frame ), GTK_SHADOW_NONE );
-
- table.attach(g_TextureBrowser.m_tag_frame, {1, 3, 2, 3}, {GTK_FILL, GTK_SHRINK});
-
- frame_table.show();
-
- g_TextureBrowser.m_tag_frame.add(frame_table);
- }
- { // assigned tag list
- ui::Widget scrolled_win = ui::ScrolledWindow(ui::New);
- gtk_container_set_border_width( GTK_CONTAINER( scrolled_win ), 0 );
- gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scrolled_win ), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS );
-
- g_TextureBrowser.m_assigned_store = ui::ListStore::from(gtk_list_store_new( N_COLUMNS, G_TYPE_STRING ));
-
- auto sortable = GTK_TREE_SORTABLE( g_TextureBrowser.m_assigned_store );
- gtk_tree_sortable_set_sort_column_id( sortable, TAG_COLUMN, GTK_SORT_ASCENDING );
-
- auto renderer = ui::CellRendererText(ui::New);
-
- g_TextureBrowser.m_assigned_tree = ui::TreeView(ui::TreeModel::from(g_TextureBrowser.m_assigned_store._handle));
- g_TextureBrowser.m_assigned_store.unref();
- g_TextureBrowser.m_assigned_tree.connect( "row-activated", (GCallback) TextureBrowser_removeTags, NULL );
- gtk_tree_view_set_headers_visible(g_TextureBrowser.m_assigned_tree, FALSE );
-
- auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_assigned_tree );
- gtk_tree_selection_set_mode( selection, GTK_SELECTION_MULTIPLE );
-
- auto column = ui::TreeViewColumn( "", renderer, {{"text", TAG_COLUMN}} );
- gtk_tree_view_append_column(g_TextureBrowser.m_assigned_tree, column );
- g_TextureBrowser.m_assigned_tree.show();
-
- scrolled_win.show();
- gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( scrolled_win ), g_TextureBrowser.m_assigned_tree );
-
- frame_table.attach(scrolled_win, {0, 1, 1, 3}, {GTK_FILL, GTK_FILL});
- }
- { // available tag list
- ui::Widget scrolled_win = ui::ScrolledWindow(ui::New);
- gtk_container_set_border_width( GTK_CONTAINER( scrolled_win ), 0 );
- gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scrolled_win ), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS );
-
- g_TextureBrowser.m_available_store = ui::ListStore::from(gtk_list_store_new( N_COLUMNS, G_TYPE_STRING ));
- auto sortable = GTK_TREE_SORTABLE( g_TextureBrowser.m_available_store );
- gtk_tree_sortable_set_sort_column_id( sortable, TAG_COLUMN, GTK_SORT_ASCENDING );
-
- auto renderer = ui::CellRendererText(ui::New);
-
- g_TextureBrowser.m_available_tree = ui::TreeView(ui::TreeModel::from(g_TextureBrowser.m_available_store._handle));
- g_TextureBrowser.m_available_store.unref();
- g_TextureBrowser.m_available_tree.connect( "row-activated", (GCallback) TextureBrowser_assignTags, NULL );
- gtk_tree_view_set_headers_visible(g_TextureBrowser.m_available_tree, FALSE );
-
- auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_available_tree );
- gtk_tree_selection_set_mode( selection, GTK_SELECTION_MULTIPLE );
-
- auto column = ui::TreeViewColumn( "", renderer, {{"text", TAG_COLUMN}} );
- gtk_tree_view_append_column(g_TextureBrowser.m_available_tree, column );
- g_TextureBrowser.m_available_tree.show();
-
- scrolled_win.show();
- gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( scrolled_win ), g_TextureBrowser.m_available_tree );
-
- frame_table.attach(scrolled_win, {2, 3, 1, 3}, {GTK_FILL, GTK_FILL});
- }
- { // tag arrow buttons
- auto m_btn_left = ui::Button(ui::New);
- auto m_btn_right = ui::Button(ui::New);
- auto m_arrow_left = ui::Widget::from(gtk_arrow_new( GTK_ARROW_LEFT, GTK_SHADOW_OUT ));
- auto m_arrow_right = ui::Widget::from(gtk_arrow_new( GTK_ARROW_RIGHT, GTK_SHADOW_OUT ));
- m_btn_left.add(m_arrow_left);
- m_btn_right.add(m_arrow_right);
-
- // workaround. the size of the tag frame depends of the requested size of the arrow buttons.
- m_arrow_left.dimensions(-1, 68);
- m_arrow_right.dimensions(-1, 68);
-
- frame_table.attach(m_btn_left, {1, 2, 1, 2}, {GTK_SHRINK, GTK_EXPAND});
- frame_table.attach(m_btn_right, {1, 2, 2, 3}, {GTK_SHRINK, GTK_EXPAND});
-
- m_btn_left.connect( "clicked", G_CALLBACK( TextureBrowser_assignTags ), NULL );
- m_btn_right.connect( "clicked", G_CALLBACK( TextureBrowser_removeTags ), NULL );
-
- m_btn_left.show();
- m_btn_right.show();
- m_arrow_left.show();
- m_arrow_right.show();
- }
- { // tag fram labels
- ui::Widget m_lbl_assigned = ui::Label( "Assigned" );
- ui::Widget m_lbl_unassigned = ui::Label( "Available" );
-
- frame_table.attach(m_lbl_assigned, {0, 1, 0, 1}, {GTK_EXPAND, GTK_SHRINK});
- frame_table.attach(m_lbl_unassigned, {2, 3, 0, 1}, {GTK_EXPAND, GTK_SHRINK});
-
- m_lbl_assigned.show();
- m_lbl_unassigned.show();
- }
- }
- else { // no tag support, show the texture tree only
- vbox.pack_start( g_TextureBrowser.m_scr_win_tree, TRUE, TRUE, 0 );
- }
-
- // TODO do we need this?
- //gtk_container_set_focus_chain(GTK_CONTAINER(hbox_table), NULL);
-
- return table;
-}
-
-void TextureBrowser_destroyWindow(){
- GlobalShaderSystem().setActiveShadersChangedNotify( Callback<void()>() );
-
- g_signal_handler_disconnect( G_OBJECT( g_TextureBrowser.m_gl_widget ), g_TextureBrowser.m_sizeHandler );
- g_signal_handler_disconnect( G_OBJECT( g_TextureBrowser.m_gl_widget ), g_TextureBrowser.m_exposeHandler );
-
- g_TextureBrowser.m_gl_widget.unref();
-}
-
-const Vector3& TextureBrowser_getBackgroundColour( TextureBrowser& textureBrowser ){
- return textureBrowser.color_textureback;
-}
-
-void TextureBrowser_setBackgroundColour( TextureBrowser& textureBrowser, const Vector3& colour ){
- textureBrowser.color_textureback = colour;
- TextureBrowser_queueDraw( textureBrowser );
-}
-
-void TextureBrowser_selectionHelper( ui::TreeModel model, ui::TreePath path, GtkTreeIter* iter, GSList** selected ){
- g_assert( selected != NULL );
-
- gchar* name;
- gtk_tree_model_get( model, iter, TAG_COLUMN, &name, -1 );
- *selected = g_slist_append( *selected, name );
-}
-
-void TextureBrowser_shaderInfo(){
- const char* name = TextureBrowser_GetSelectedShader( g_TextureBrowser );
- IShader* shader = QERApp_Shader_ForName( name );
-
- DoShaderInfoDlg( name, shader->getShaderFileName(), "Shader Info" );
-
- shader->DecRef();
-}
-
-void TextureBrowser_addTag(){
- CopiedString tag;
-
- EMessageBoxReturn result = DoShaderTagDlg( &tag, "Add shader tag" );
-
- if ( result == eIDOK && !tag.empty() ) {
- GtkTreeIter iter;
- g_TextureBrowser.m_all_tags.insert( tag.c_str() );
- gtk_list_store_append( g_TextureBrowser.m_available_store, &iter );
- gtk_list_store_set( g_TextureBrowser.m_available_store, &iter, TAG_COLUMN, tag.c_str(), -1 );
-
- // Select the currently added tag in the available list
- auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_available_tree );
- gtk_tree_selection_select_iter( selection, &iter );
-
- g_TextureBrowser.m_all_tags_list.append(TAG_COLUMN, tag.c_str());
- }
-}
-
-void TextureBrowser_renameTag(){
- /* WORKAROUND: The tag treeview is set to GTK_SELECTION_MULTIPLE. Because
- gtk_tree_selection_get_selected() doesn't work with GTK_SELECTION_MULTIPLE,
- we need to count the number of selected rows first and use
- gtk_tree_selection_selected_foreach() then to go through the list of selected
- rows (which always containins a single row).
- */
-
- GSList* selected = NULL;
-
- auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_treeViewTags );
- gtk_tree_selection_selected_foreach( selection, GtkTreeSelectionForeachFunc( TextureBrowser_selectionHelper ), &selected );
-
- if ( g_slist_length( selected ) == 1 ) { // we only rename a single tag
- CopiedString newTag;
- EMessageBoxReturn result = DoShaderTagDlg( &newTag, "Rename shader tag" );
-
- if ( result == eIDOK && !newTag.empty() ) {
- GtkTreeIter iterList;
- gchar* rowTag;
- gchar* oldTag = (char*)selected->data;
-
- bool row = gtk_tree_model_get_iter_first(g_TextureBrowser.m_all_tags_list, &iterList ) != 0;
-
- while ( row )
- {
- gtk_tree_model_get(g_TextureBrowser.m_all_tags_list, &iterList, TAG_COLUMN, &rowTag, -1 );
-
- if ( strcmp( rowTag, oldTag ) == 0 ) {
- gtk_list_store_set( g_TextureBrowser.m_all_tags_list, &iterList, TAG_COLUMN, newTag.c_str(), -1 );
- }
- row = gtk_tree_model_iter_next(g_TextureBrowser.m_all_tags_list, &iterList ) != 0;
- }
-
- TagBuilder.RenameShaderTag( oldTag, newTag.c_str() );
-
- g_TextureBrowser.m_all_tags.erase( (CopiedString)oldTag );
- g_TextureBrowser.m_all_tags.insert( newTag );
-
- BuildStoreAssignedTags( g_TextureBrowser.m_assigned_store, g_TextureBrowser.shader.c_str(), &g_TextureBrowser );
- BuildStoreAvailableTags( g_TextureBrowser.m_available_store, g_TextureBrowser.m_assigned_store, g_TextureBrowser.m_all_tags, &g_TextureBrowser );
- }
- }
- else
- {
- ui::alert( g_TextureBrowser.m_parent, "Select a single tag for renaming." );
- }
-}
-
-void TextureBrowser_deleteTag(){
- GSList* selected = NULL;
-
- auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_treeViewTags );
- gtk_tree_selection_selected_foreach( selection, GtkTreeSelectionForeachFunc( TextureBrowser_selectionHelper ), &selected );
-
- if ( g_slist_length( selected ) == 1 ) { // we only delete a single tag
- auto result = ui::alert( g_TextureBrowser.m_parent, "Are you sure you want to delete the selected tag?", "Delete Tag", ui::alert_type::YESNO, ui::alert_icon::Question );
-
- if ( result == ui::alert_response::YES ) {
- GtkTreeIter iterSelected;
- gchar *rowTag;
-
- gchar* tagSelected = (char*)selected->data;
-
- bool row = gtk_tree_model_get_iter_first(g_TextureBrowser.m_all_tags_list, &iterSelected ) != 0;
-
- while ( row )
- {
- gtk_tree_model_get(g_TextureBrowser.m_all_tags_list, &iterSelected, TAG_COLUMN, &rowTag, -1 );
-
- if ( strcmp( rowTag, tagSelected ) == 0 ) {
- gtk_list_store_remove( g_TextureBrowser.m_all_tags_list, &iterSelected );
- break;
- }
- row = gtk_tree_model_iter_next(g_TextureBrowser.m_all_tags_list, &iterSelected ) != 0;
- }
-
- TagBuilder.DeleteTag( tagSelected );
- g_TextureBrowser.m_all_tags.erase( (CopiedString)tagSelected );
-
- BuildStoreAssignedTags( g_TextureBrowser.m_assigned_store, g_TextureBrowser.shader.c_str(), &g_TextureBrowser );
- BuildStoreAvailableTags( g_TextureBrowser.m_available_store, g_TextureBrowser.m_assigned_store, g_TextureBrowser.m_all_tags, &g_TextureBrowser );
- }
- }
- else {
- ui::alert( g_TextureBrowser.m_parent, "Select a single tag for deletion." );
- }
-}
-
-void TextureBrowser_copyTag(){
- g_TextureBrowser.m_copied_tags.clear();
- TagBuilder.GetShaderTags( g_TextureBrowser.shader.c_str(), g_TextureBrowser.m_copied_tags );
-}
-
-void TextureBrowser_pasteTag(){
- IShader* ishader = QERApp_Shader_ForName( g_TextureBrowser.shader.c_str() );
- CopiedString shader = g_TextureBrowser.shader.c_str();
-
- if ( !TagBuilder.CheckShaderTag( shader.c_str() ) ) {
- CopiedString shaderFile = ishader->getShaderFileName();
- if ( shaderFile.empty() ) {
- // it's a texture
- TagBuilder.AddShaderNode( shader.c_str(), CUSTOM, TEXTURE );
- }
- else
- {
- // it's a shader
- TagBuilder.AddShaderNode( shader.c_str(), CUSTOM, SHADER );
- }
-
- for ( size_t i = 0; i < g_TextureBrowser.m_copied_tags.size(); ++i )
- {
- TagBuilder.AddShaderTag( shader.c_str(), g_TextureBrowser.m_copied_tags[i].c_str(), TAG );
- }
- }
- else
- {
- for ( size_t i = 0; i < g_TextureBrowser.m_copied_tags.size(); ++i )
- {
- if ( !TagBuilder.CheckShaderTag( shader.c_str(), g_TextureBrowser.m_copied_tags[i].c_str() ) ) {
- // the tag doesn't exist - let's add it
- TagBuilder.AddShaderTag( shader.c_str(), g_TextureBrowser.m_copied_tags[i].c_str(), TAG );
- }
- }
- }
-
- ishader->DecRef();
-
- TagBuilder.SaveXmlDoc();
- BuildStoreAssignedTags( g_TextureBrowser.m_assigned_store, shader.c_str(), &g_TextureBrowser );
- BuildStoreAvailableTags( g_TextureBrowser.m_available_store, g_TextureBrowser.m_assigned_store, g_TextureBrowser.m_all_tags, &g_TextureBrowser );
-}
-
-void TextureBrowser_RefreshShaders(){
-
- /* When shaders are refreshed, forces reloading the textures as well.
- Previously it would at best only display shaders, at worst mess up some textured objects. */
-
- auto selection = gtk_tree_view_get_selection(GlobalTextureBrowser().m_treeViewTree);
- GtkTreeModel* model = NULL;
- GtkTreeIter iter;
- if ( gtk_tree_selection_get_selected (selection, &model, &iter) )
- {
- gchar dirName[1024];
-
- gchar* buffer;
- gtk_tree_model_get( model, &iter, 0, &buffer, -1 );
- strcpy( dirName, buffer );
- g_free( buffer );
- if ( !TextureBrowser_showWads() ) {
- strcat( dirName, "/" );
- }
-
- ScopeDisableScreenUpdates disableScreenUpdates( "Processing...", "Loading Shaders" );
- GlobalShaderSystem().refresh();
- /* texturebrowser tree update on vfs restart */
- TextureBrowser_constructTreeStore();
- UpdateAllWindows();
-
- TextureBrowser_ShowDirectory( GlobalTextureBrowser(), dirName );
- TextureBrowser_queueDraw( GlobalTextureBrowser() );
- }
-
- else{
- ScopeDisableScreenUpdates disableScreenUpdates( "Processing...", "Loading Shaders" );
- GlobalShaderSystem().refresh();
- /* texturebrowser tree update on vfs restart */
- TextureBrowser_constructTreeStore();
- UpdateAllWindows();
- }
-}
-
-void TextureBrowser_ToggleShowShaders(){
- g_TextureBrowser.m_showShaders ^= 1;
- g_TextureBrowser.m_showshaders_item.update();
-
- g_TextureBrowser.m_heightChanged = true;
- g_TextureBrowser.m_originInvalid = true;
- g_activeShadersChangedCallbacks();
-
- TextureBrowser_queueDraw( g_TextureBrowser );
-}
-
-void TextureBrowser_ToggleShowTextures(){
- g_TextureBrowser.m_showTextures ^= 1;
- g_TextureBrowser.m_showtextures_item.update();
-
- g_TextureBrowser.m_heightChanged = true;
- g_TextureBrowser.m_originInvalid = true;
- g_activeShadersChangedCallbacks();
-
- TextureBrowser_queueDraw( g_TextureBrowser );
-}
-
-void TextureBrowser_ToggleShowShaderListOnly(){
- g_TextureBrowser_shaderlistOnly ^= 1;
- g_TextureBrowser.m_showshaderlistonly_item.update();
-
- TextureBrowser_constructTreeStore();
-}
-
-void TextureBrowser_showAll(){
- g_TextureBrowser_currentDirectory = "";
- g_TextureBrowser.m_searchedTags = false;
-// TextureBrowser_SetHideUnused( g_TextureBrowser, false );
- TextureBrowser_ToggleHideUnused();
- //TextureBrowser_heightChanged( g_TextureBrowser );
- TextureBrowser_updateTitle();
-}
-
-void TextureBrowser_showUntagged(){
- auto result = ui::alert( g_TextureBrowser.m_parent, "WARNING! This function might need a lot of memory and time. Are you sure you want to use it?", "Show Untagged", ui::alert_type::YESNO, ui::alert_icon::Warning );
-
- if ( result == ui::alert_response::YES ) {
- g_TextureBrowser.m_found_shaders.clear();
- TagBuilder.GetUntagged( g_TextureBrowser.m_found_shaders );
- std::set<CopiedString>::iterator iter;
-
- ScopeDisableScreenUpdates disableScreenUpdates( "Searching untagged textures...", "Loading Textures" );
-
- for ( iter = g_TextureBrowser.m_found_shaders.begin(); iter != g_TextureBrowser.m_found_shaders.end(); iter++ )
- {
- std::string path = ( *iter ).c_str();
- size_t pos = path.find_last_of( "/", path.size() );
- std::string name = path.substr( pos + 1, path.size() );
- path = path.substr( 0, pos + 1 );
- TextureDirectory_loadTexture( path.c_str(), name.c_str() );
- globalErrorStream() << path.c_str() << name.c_str() << "\n";
- }
-
- g_TextureBrowser_currentDirectory = "Untagged";
- TextureBrowser_queueDraw( GlobalTextureBrowser() );
- TextureBrowser_heightChanged( g_TextureBrowser );
- TextureBrowser_updateTitle();
- }
-}
-
-void TextureBrowser_FixedSize(){
- g_TextureBrowser_fixedSize ^= 1;
- GlobalTextureBrowser().m_fixedsize_item.update();
- TextureBrowser_activeShadersChanged( GlobalTextureBrowser() );
-}
-
-void TextureBrowser_FilterMissing(){
- g_TextureBrowser_filterMissing ^= 1;
- GlobalTextureBrowser().m_filternotex_item.update();
- TextureBrowser_activeShadersChanged( GlobalTextureBrowser() );
- TextureBrowser_RefreshShaders();
-}
-
-void TextureBrowser_FilterFallback(){
- g_TextureBrowser_filterFallback ^= 1;
- GlobalTextureBrowser().m_hidenotex_item.update();
- TextureBrowser_activeShadersChanged( GlobalTextureBrowser() );
- TextureBrowser_RefreshShaders();
-}
-
-void TextureBrowser_EnableAlpha(){
- g_TextureBrowser_enableAlpha ^= 1;
- GlobalTextureBrowser().m_enablealpha_item.update();
- TextureBrowser_activeShadersChanged( GlobalTextureBrowser() );
-}
-
-void TextureBrowser_exportTitle( const Callback<void(const char *)> & importer ){
- StringOutputStream buffer( 64 );
- buffer << "Textures: ";
- if ( !string_empty( g_TextureBrowser_currentDirectory.c_str() ) ) {
- buffer << g_TextureBrowser_currentDirectory.c_str();
- }
- else
- {
- buffer << "all";
- }
- importer( buffer.c_str() );
-}
-
-struct TextureScale {
- static void Export(const TextureBrowser &self, const Callback<void(int)> &returnz) {
- switch (self.m_textureScale) {
- case 10:
- returnz(0);
- break;
- case 25:
- returnz(1);
- break;
- case 50:
- returnz(2);
- break;
- case 100:
- returnz(3);
- break;
- case 200:
- returnz(4);
- break;
- }
- }
-
- static void Import(TextureBrowser &self, int value) {
- switch (value) {
- case 0:
- TextureBrowser_setScale(self, 10);
- break;
- case 1:
- TextureBrowser_setScale(self, 25);
- break;
- case 2:
- TextureBrowser_setScale(self, 50);
- break;
- case 3:
- TextureBrowser_setScale(self, 100);
- break;
- case 4:
- TextureBrowser_setScale(self, 200);
- break;
- }
- }
-};
-
-struct UniformTextureSize {
- static void Export(const TextureBrowser &self, const Callback<void(int)> &returnz) {
- returnz(g_TextureBrowser.m_uniformTextureSize);
- }
-
- static void Import(TextureBrowser &self, int value) {
- if (value > 16)
- TextureBrowser_setUniformSize(self, value);
- }
-};
-
-struct UniformTextureMinSize {
- static void Export(const TextureBrowser &self, const Callback<void(int)> &returnz) {
- returnz(g_TextureBrowser.m_uniformTextureMinSize);
- }
-
- static void Import(TextureBrowser &self, int value) {
- if (value > 16)
- TextureBrowser_setUniformSize(self, value);
- }
-};
-
-void TextureBrowser_constructPreferences( PreferencesPage& page ){
- page.appendCheckBox(
- "", "Texture scrollbar",
- make_property<TextureBrowser_ShowScrollbar>(GlobalTextureBrowser())
- );
- {
- const char* texture_scale[] = { "10%", "25%", "50%", "100%", "200%" };
- page.appendCombo(
- "Texture Thumbnail Scale",
- STRING_ARRAY_RANGE( texture_scale ),
- make_property<TextureScale>(GlobalTextureBrowser())
- );
- }
- page.appendSpinner( "Thumbnails Max Size", GlobalTextureBrowser().m_uniformTextureSize, GlobalTextureBrowser().m_uniformTextureSize, 16, 8192 );
- page.appendSpinner( "Thumbnails Min Size", GlobalTextureBrowser().m_uniformTextureMinSize, GlobalTextureBrowser().m_uniformTextureMinSize, 16, 8192 );
- page.appendEntry( "Mousewheel Increment", GlobalTextureBrowser().m_mouseWheelScrollIncrement );
- {
- const char* startup_shaders[] = { "None", TextureBrowser_getComonShadersName() };
- page.appendCombo( "Load Shaders at Startup", reinterpret_cast<int&>( GlobalTextureBrowser().m_startupShaders ), STRING_ARRAY_RANGE( startup_shaders ) );
- }
- {
- StringOutputStream sstream( 256 );
- sstream << "Hide nonShaders in " << TextureBrowser_getComonShadersDir() << " folder";
- page.appendCheckBox(
- "", sstream.c_str(),
- GlobalTextureBrowser().m_hideNonShadersInCommon
- );
- }
-}
-
-void TextureBrowser_constructPage( PreferenceGroup& group ){
- PreferencesPage page( group.createPage( "Texture Browser", "Texture Browser Preferences" ) );
- TextureBrowser_constructPreferences( page );
-}
-
-void TextureBrowser_registerPreferencesPage(){
- PreferencesDialog_addSettingsPage( makeCallbackF(TextureBrowser_constructPage) );
-}
-
-
-#include "preferencesystem.h"
-#include "stringio.h"
-
-
-void TextureClipboard_textureSelected( const char* shader );
-
-void TextureBrowser_Construct(){
-<<<<<<< HEAD
- GlobalCommands_insert( "ShaderInfo", makeCallbackF(TextureBrowser_shaderInfo) );
- GlobalCommands_insert( "ShowUntagged", makeCallbackF(TextureBrowser_showUntagged) );
- GlobalCommands_insert( "AddTag", makeCallbackF(TextureBrowser_addTag) );
- GlobalCommands_insert( "RenameTag", makeCallbackF(TextureBrowser_renameTag) );
- GlobalCommands_insert( "DeleteTag", makeCallbackF(TextureBrowser_deleteTag) );
- GlobalCommands_insert( "CopyTag", makeCallbackF(TextureBrowser_copyTag) );
- GlobalCommands_insert( "PasteTag", makeCallbackF(TextureBrowser_pasteTag) );
- GlobalCommands_insert( "RefreshShaders", makeCallbackF(VFS_Refresh) );
- GlobalToggles_insert( "ShowInUse", makeCallbackF(TextureBrowser_ToggleHideUnused), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_hideunused_item ), Accelerator( 'U' ) );
- GlobalCommands_insert( "ShowAllTextures", makeCallbackF(TextureBrowser_showAll), Accelerator( 'A', (GdkModifierType)GDK_CONTROL_MASK ) );
- GlobalCommands_insert( "ToggleTextures", makeCallbackF(TextureBrowser_toggleShow), Accelerator( 'T' ) );
- GlobalToggles_insert( "ToggleShowShaders", makeCallbackF(TextureBrowser_ToggleShowShaders), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_showshaders_item ) );
- GlobalToggles_insert( "ToggleShowTextures", makeCallbackF(TextureBrowser_ToggleShowTextures), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_showtextures_item ) );
- GlobalToggles_insert( "ToggleShowShaderlistOnly", makeCallbackF(TextureBrowser_ToggleShowShaderListOnly),
- ToggleItem::AddCallbackCaller( g_TextureBrowser.m_showshaderlistonly_item ) );
- GlobalToggles_insert( "FixedSize", makeCallbackF(TextureBrowser_FixedSize), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_fixedsize_item ) );
- GlobalToggles_insert( "FilterMissing", makeCallbackF(TextureBrowser_FilterMissing), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_filternotex_item ) );
- GlobalToggles_insert( "FilterFallback", makeCallbackF(TextureBrowser_FilterFallback), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_hidenotex_item ) );
- GlobalToggles_insert( "EnableAlpha", makeCallbackF(TextureBrowser_EnableAlpha), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_enablealpha_item ) );
-
- GlobalPreferenceSystem().registerPreference( "TextureScale", make_property_string<TextureScale>(g_TextureBrowser) );
- GlobalPreferenceSystem().registerPreference( "UniformTextureSize", make_property_string<UniformTextureSize>(g_TextureBrowser) );
- GlobalPreferenceSystem().registerPreference( "UniformTextureMinSize", make_property_string<UniformTextureMinSize>(g_TextureBrowser) );
- GlobalPreferenceSystem().registerPreference( "TextureScrollbar", make_property_string<TextureBrowser_ShowScrollbar>(GlobalTextureBrowser()));
- GlobalPreferenceSystem().registerPreference( "ShowShaders", make_property_string( GlobalTextureBrowser().m_showShaders ) );
- GlobalPreferenceSystem().registerPreference( "ShowTextures", make_property_string( GlobalTextureBrowser().m_showTextures ) );
- GlobalPreferenceSystem().registerPreference( "ShowShaderlistOnly", make_property_string( g_TextureBrowser_shaderlistOnly ) );
- GlobalPreferenceSystem().registerPreference( "FixedSize", make_property_string( g_TextureBrowser_fixedSize ) );
- GlobalPreferenceSystem().registerPreference( "FilterMissing", make_property_string( g_TextureBrowser_filterMissing ) );
- GlobalPreferenceSystem().registerPreference( "EnableAlpha", make_property_string( g_TextureBrowser_enableAlpha ) );
- GlobalPreferenceSystem().registerPreference( "LoadShaders", make_property_string( reinterpret_cast<int&>( GlobalTextureBrowser().m_startupShaders ) ) );
- GlobalPreferenceSystem().registerPreference( "WheelMouseInc", make_property_string( GlobalTextureBrowser().m_mouseWheelScrollIncrement ) );
- GlobalPreferenceSystem().registerPreference( "SI_Colors0", make_property_string( GlobalTextureBrowser().color_textureback ) );
-=======
- GlobalCommands_insert( "ShaderInfo", FreeCaller<TextureBrowser_shaderInfo>() );
- GlobalCommands_insert( "ShowUntagged", FreeCaller<TextureBrowser_showUntagged>() );
- GlobalCommands_insert( "AddTag", FreeCaller<TextureBrowser_addTag>() );
- GlobalCommands_insert( "RenameTag", FreeCaller<TextureBrowser_renameTag>() );
- GlobalCommands_insert( "DeleteTag", FreeCaller<TextureBrowser_deleteTag>() );
- GlobalCommands_insert( "CopyTag", FreeCaller<TextureBrowser_copyTag>() );
- GlobalCommands_insert( "PasteTag", FreeCaller<TextureBrowser_pasteTag>() );
- GlobalCommands_insert( "RefreshShaders", FreeCaller<RefreshShaders>() );
- GlobalToggles_insert( "ShowInUse", FreeCaller<TextureBrowser_ToggleHideUnused>(), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_hideunused_item ), Accelerator( 'U' ) );
- GlobalCommands_insert( "ShowAllTextures", FreeCaller<TextureBrowser_showAll>(), Accelerator( 'A', (GdkModifierType)GDK_CONTROL_MASK ) );
- GlobalCommands_insert( "ToggleTextures", FreeCaller<TextureBrowser_toggleShow>(), Accelerator( 'T' ) );
- GlobalToggles_insert( "ToggleShowShaders", FreeCaller<TextureBrowser_ToggleShowShaders>(), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_showshaders_item ) );
- GlobalToggles_insert( "ToggleShowTextures", FreeCaller<TextureBrowser_ToggleShowTextures>(), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_showtextures_item ) );
- GlobalToggles_insert( "ToggleShowShaderlistOnly", FreeCaller<TextureBrowser_ToggleShowShaderListOnly>(), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_showshaderlistonly_item ) );
- GlobalToggles_insert( "FixedSize", FreeCaller<TextureBrowser_FixedSize>(), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_fixedsize_item ) );
- GlobalToggles_insert( "FilterNotex", FreeCaller<TextureBrowser_FilterNotex>(), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_filternotex_item ) );
- GlobalToggles_insert( "EnableAlpha", FreeCaller<TextureBrowser_EnableAlpha>(), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_enablealpha_item ) );
-
- GlobalPreferenceSystem().registerPreference( "TextureScale",
- makeSizeStringImportCallback( TextureBrowserSetScaleCaller( g_TextureBrowser ) ),
- SizeExportStringCaller( g_TextureBrowser.m_textureScale )
- );
- GlobalPreferenceSystem().registerPreference( "UniformTextureSize",
- makeIntStringImportCallback(UniformTextureSizeImportCaller(g_TextureBrowser)),
- IntExportStringCaller(g_TextureBrowser.m_uniformTextureSize) );
- GlobalPreferenceSystem().registerPreference( "UniformTextureMinSize",
- makeIntStringImportCallback(UniformTextureMinSizeImportCaller(g_TextureBrowser)),
- IntExportStringCaller(g_TextureBrowser.m_uniformTextureMinSize) );
- GlobalPreferenceSystem().registerPreference( "TextureScrollbar",
- makeBoolStringImportCallback( TextureBrowserImportShowScrollbarCaller( g_TextureBrowser ) ),
- BoolExportStringCaller( GlobalTextureBrowser().m_showTextureScrollbar )
- );
- GlobalPreferenceSystem().registerPreference( "ShowShaders", BoolImportStringCaller( GlobalTextureBrowser().m_showShaders ), BoolExportStringCaller( GlobalTextureBrowser().m_showShaders ) );
- GlobalPreferenceSystem().registerPreference( "ShowTextures", BoolImportStringCaller( GlobalTextureBrowser().m_showTextures ), BoolExportStringCaller( GlobalTextureBrowser().m_showTextures ) );
- GlobalPreferenceSystem().registerPreference( "ShowShaderlistOnly", BoolImportStringCaller( g_TextureBrowser_shaderlistOnly ), BoolExportStringCaller( g_TextureBrowser_shaderlistOnly ) );
- GlobalPreferenceSystem().registerPreference( "FixedSize", BoolImportStringCaller( g_TextureBrowser_fixedSize ), BoolExportStringCaller( g_TextureBrowser_fixedSize ) );
- GlobalPreferenceSystem().registerPreference( "FilterNotex", BoolImportStringCaller( g_TextureBrowser_filterNotex ), BoolExportStringCaller( g_TextureBrowser_filterNotex ) );
- GlobalPreferenceSystem().registerPreference( "EnableAlpha", BoolImportStringCaller( g_TextureBrowser_enableAlpha ), BoolExportStringCaller( g_TextureBrowser_enableAlpha ) );
- GlobalPreferenceSystem().registerPreference( "LoadShaders", IntImportStringCaller( reinterpret_cast<int&>( GlobalTextureBrowser().m_startupShaders ) ), IntExportStringCaller( reinterpret_cast<int&>( GlobalTextureBrowser().m_startupShaders ) ) );
- GlobalPreferenceSystem().registerPreference( "WheelMouseInc", SizeImportStringCaller( GlobalTextureBrowser().m_mouseWheelScrollIncrement ), SizeExportStringCaller( GlobalTextureBrowser().m_mouseWheelScrollIncrement ) );
- GlobalPreferenceSystem().registerPreference( "SI_Colors0", Vector3ImportStringCaller( GlobalTextureBrowser().color_textureback ), Vector3ExportStringCaller( GlobalTextureBrowser().color_textureback ) );
- GlobalPreferenceSystem().registerPreference( "HideNonShadersInCommon", BoolImportStringCaller( GlobalTextureBrowser().m_hideNonShadersInCommon ), BoolExportStringCaller( GlobalTextureBrowser().m_hideNonShadersInCommon ) );
->>>>>>> 3a78d902017a780e65f21f12c709aa746dfcab84
-
- g_TextureBrowser.shader = texdef_name_default();
-
- Textures_setModeChangedNotify( ReferenceCaller<TextureBrowser, void(), TextureBrowser_queueDraw>( g_TextureBrowser ) );
-
- TextureBrowser_registerPreferencesPage();
-
- GlobalShaderSystem().attach( g_ShadersObserver );
-
- TextureBrowser_textureSelected = TextureClipboard_textureSelected;
-}
-
-void TextureBrowser_Destroy(){
- GlobalShaderSystem().detach( g_ShadersObserver );
-
- Textures_setModeChangedNotify( Callback<void()>() );
-}
-
-ui::Widget TextureBrowser_getGLWidget(){
- return GlobalTextureBrowser().m_gl_widget;
-}