]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - radiant/camwindow.cpp
Merge commit 'c845c5cd8f427d39665d6a8b1f6eeff401370d80' into garux-merge
[xonotic/netradiant.git] / radiant / camwindow.cpp
index 358d1b51711fa7b4634d97996941c585bfe70dc1..eafc1da093d41d8bf1044178492d1baefc792c74 100644 (file)
@@ -706,7 +706,7 @@ static void releaseStates(){
 
 camera_t& getCamera(){
        return m_Camera;
-};
+}
 
 void BenchMark();
 void Cam_ChangeFloor( bool up );
@@ -1648,6 +1648,50 @@ void GlobalCamera_ResetAngles(){
        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 );
@@ -1912,6 +1956,7 @@ void CameraSpeed_decrease(){
 /// \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 ) );