X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=libs%2Fpivot.h;h=93cb354941cb79071908c7c489020bae814d9509;hb=9e8a1acd8cdd8f3d2c963aa38d468105fef18a21;hp=9e9c137c9beb2c1193b54af86e5a159eda91bf97;hpb=231225d6f97d0b926b2e896e5783cccfbc7c5619;p=xonotic%2Fnetradiant.git diff --git a/libs/pivot.h b/libs/pivot.h index 9e9c137c..93cb3549 100644 --- a/libs/pivot.h +++ b/libs/pivot.h @@ -1,233 +1,222 @@ /* -Copyright (C) 2001-2006, William Joseph. -All Rights Reserved. + Copyright (C) 2001-2006, William Joseph. + All Rights Reserved. -This file is part of GtkRadiant. + 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 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. + 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 -*/ + 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_PIVOT_H) +#if !defined( INCLUDED_PIVOT_H ) #define INCLUDED_PIVOT_H #include "math/matrix.h" -inline void billboard_viewplaneOriented(Matrix4& rotation, const Matrix4& world2screen) -{ +inline void billboard_viewplaneOriented( Matrix4& rotation, const Matrix4& world2screen ){ #if 1 - rotation = g_matrix4_identity; - Vector3 x(vector3_normalised(vector4_to_vector3(world2screen.x()))); - Vector3 y(vector3_normalised(vector4_to_vector3(world2screen.y()))); - Vector3 z(vector3_normalised(vector4_to_vector3(world2screen.z()))); - vector4_to_vector3(rotation.y()) = Vector3(x.y(), y.y(), z.y()); - vector4_to_vector3(rotation.z()) = vector3_negated(Vector3(x.z(), y.z(), z.z())); - vector4_to_vector3(rotation.x()) = vector3_normalised(vector3_cross(vector4_to_vector3(rotation.y()), vector4_to_vector3(rotation.z()))); - vector4_to_vector3(rotation.y()) = vector3_cross(vector4_to_vector3(rotation.z()), vector4_to_vector3(rotation.x())); + rotation = g_matrix4_identity; + Vector3 x( vector3_normalised( vector4_to_vector3( world2screen.x() ) ) ); + Vector3 y( vector3_normalised( vector4_to_vector3( world2screen.y() ) ) ); + Vector3 z( vector3_normalised( vector4_to_vector3( world2screen.z() ) ) ); + vector4_to_vector3( rotation.y() ) = Vector3( x.y(), y.y(), z.y() ); + vector4_to_vector3( rotation.z() ) = vector3_negated( Vector3( x.z(), y.z(), z.z() ) ); + vector4_to_vector3( rotation.x() ) = vector3_normalised( vector3_cross( vector4_to_vector3( rotation.y() ), vector4_to_vector3( rotation.z() ) ) ); + vector4_to_vector3( rotation.y() ) = vector3_cross( vector4_to_vector3( rotation.z() ), vector4_to_vector3( rotation.x() ) ); #else - Matrix4 screen2world(matrix4_full_inverse(world2screen)); - - Vector3 near_( - vector4_projected( - matrix4_transformed_vector4( - screen2world, - Vector4(0, 0, -1, 1) - ) - ) - ); - - Vector3 far_( - vector4_projected( - matrix4_transformed_vector4( - screen2world, - Vector4(0, 0, 1, 1) - ) - ) - ); - - Vector3 up( - vector4_projected( - matrix4_transformed_vector4( - screen2world, - Vector4(0, 1, -1, 1) - ) - ) - ); - - rotation = g_matrix4_identity; - vector4_to_vector3(rotation.y()) = vector3_normalised(vector3_subtracted(up, near_)); - vector4_to_vector3(rotation.z()) = vector3_normalised(vector3_subtracted(near_, far_)); - vector4_to_vector3(rotation.x()) = vector3_normalised(vector3_cross(vector4_to_vector3(rotation.y()), vector4_to_vector3(rotation.z()))); - vector4_to_vector3(rotation.y()) = vector3_cross(vector4_to_vector3(rotation.z()), vector4_to_vector3(rotation.x())); + Matrix4 screen2world( matrix4_full_inverse( world2screen ) ); + + Vector3 near_( + vector4_projected( + matrix4_transformed_vector4( + screen2world, + Vector4( 0, 0, -1, 1 ) + ) + ) + ); + + Vector3 far_( + vector4_projected( + matrix4_transformed_vector4( + screen2world, + Vector4( 0, 0, 1, 1 ) + ) + ) + ); + + Vector3 up( + vector4_projected( + matrix4_transformed_vector4( + screen2world, + Vector4( 0, 1, -1, 1 ) + ) + ) + ); + + rotation = g_matrix4_identity; + vector4_to_vector3( rotation.y() ) = vector3_normalised( vector3_subtracted( up, near_ ) ); + vector4_to_vector3( rotation.z() ) = vector3_normalised( vector3_subtracted( near_, far_ ) ); + vector4_to_vector3( rotation.x() ) = vector3_normalised( vector3_cross( vector4_to_vector3( rotation.y() ), vector4_to_vector3( rotation.z() ) ) ); + vector4_to_vector3( rotation.y() ) = vector3_cross( vector4_to_vector3( rotation.z() ), vector4_to_vector3( rotation.x() ) ); #endif } -inline void billboard_viewpointOriented(Matrix4& rotation, const Matrix4& world2screen) -{ - Matrix4 screen2world(matrix4_full_inverse(world2screen)); +inline void billboard_viewpointOriented( Matrix4& rotation, const Matrix4& world2screen ){ + Matrix4 screen2world( matrix4_full_inverse( world2screen ) ); #if 1 - rotation = g_matrix4_identity; - vector4_to_vector3(rotation.y()) = vector3_normalised(vector4_to_vector3(screen2world.y())); - vector4_to_vector3(rotation.z()) = vector3_negated(vector3_normalised(vector4_to_vector3(screen2world.z()))); - vector4_to_vector3(rotation.x()) = vector3_normalised(vector3_cross(vector4_to_vector3(rotation.y()), vector4_to_vector3(rotation.z()))); - vector4_to_vector3(rotation.y()) = vector3_cross(vector4_to_vector3(rotation.z()), vector4_to_vector3(rotation.x())); + rotation = g_matrix4_identity; + vector4_to_vector3( rotation.y() ) = vector3_normalised( vector4_to_vector3( screen2world.y() ) ); + vector4_to_vector3( rotation.z() ) = vector3_negated( vector3_normalised( vector4_to_vector3( screen2world.z() ) ) ); + vector4_to_vector3( rotation.x() ) = vector3_normalised( vector3_cross( vector4_to_vector3( rotation.y() ), vector4_to_vector3( rotation.z() ) ) ); + vector4_to_vector3( rotation.y() ) = vector3_cross( vector4_to_vector3( rotation.z() ), vector4_to_vector3( rotation.x() ) ); #else - Vector3 near_( - vector4_projected( - matrix4_transformed_vector4( - screen2world, - Vector4(world2screen[12] / world2screen[15], world2screen[13] / world2screen[15], -1, 1) - ) - ) - ); - - Vector3 far_( - vector4_projected( - matrix4_transformed_vector4( - screen2world, - Vector4(world2screen[12] / world2screen[15], world2screen[13] / world2screen[15], 1, 1) - ) - ) - ); - - Vector3 up( - vector4_projected( - matrix4_transformed_vector4( - screen2world, - Vector4(world2screen[12] / world2screen[15], world2screen[13] / world2screen[15] + 1, -1, 1) - ) - ) - ); - - rotation = g_matrix4_identity; - vector4_to_vector3(rotation.y()) = vector3_normalised(vector3_subtracted(up, near_)); - vector4_to_vector3(rotation.z()) = vector3_normalised(vector3_subtracted(near_, far_)); - vector4_to_vector3(rotation.x()) = vector3_normalised(vector3_cross(vector4_to_vector3(rotation.y()), vector4_to_vector3(rotation.z()))); - vector4_to_vector3(rotation.y()) = vector3_cross(vector4_to_vector3(rotation.z()), vector4_to_vector3(rotation.x())); + Vector3 near_( + vector4_projected( + matrix4_transformed_vector4( + screen2world, + Vector4( world2screen[12] / world2screen[15], world2screen[13] / world2screen[15], -1, 1 ) + ) + ) + ); + + Vector3 far_( + vector4_projected( + matrix4_transformed_vector4( + screen2world, + Vector4( world2screen[12] / world2screen[15], world2screen[13] / world2screen[15], 1, 1 ) + ) + ) + ); + + Vector3 up( + vector4_projected( + matrix4_transformed_vector4( + screen2world, + Vector4( world2screen[12] / world2screen[15], world2screen[13] / world2screen[15] + 1, -1, 1 ) + ) + ) + ); + + rotation = g_matrix4_identity; + vector4_to_vector3( rotation.y() ) = vector3_normalised( vector3_subtracted( up, near_ ) ); + vector4_to_vector3( rotation.z() ) = vector3_normalised( vector3_subtracted( near_, far_ ) ); + vector4_to_vector3( rotation.x() ) = vector3_normalised( vector3_cross( vector4_to_vector3( rotation.y() ), vector4_to_vector3( rotation.z() ) ) ); + vector4_to_vector3( rotation.y() ) = vector3_cross( vector4_to_vector3( rotation.z() ), vector4_to_vector3( rotation.x() ) ); #endif } -inline void ConstructObject2Screen(Matrix4& object2screen, const Matrix4& object2world, const Matrix4& world2view, const Matrix4& view2device, const Matrix4& device2screen) -{ - object2screen = device2screen; - matrix4_multiply_by_matrix4(object2screen, view2device); - matrix4_multiply_by_matrix4(object2screen, world2view); - matrix4_multiply_by_matrix4(object2screen, object2world); +inline void ConstructObject2Screen( Matrix4& object2screen, const Matrix4& object2world, const Matrix4& world2view, const Matrix4& view2device, const Matrix4& device2screen ){ + object2screen = device2screen; + matrix4_multiply_by_matrix4( object2screen, view2device ); + matrix4_multiply_by_matrix4( object2screen, world2view ); + matrix4_multiply_by_matrix4( object2screen, object2world ); } -inline void ConstructObject2Device(Matrix4& object2screen, const Matrix4& object2world, const Matrix4& world2view, const Matrix4& view2device) -{ - object2screen = view2device; - matrix4_multiply_by_matrix4(object2screen, world2view); - matrix4_multiply_by_matrix4(object2screen, object2world); +inline void ConstructObject2Device( Matrix4& object2screen, const Matrix4& object2world, const Matrix4& world2view, const Matrix4& view2device ){ + object2screen = view2device; + matrix4_multiply_by_matrix4( object2screen, world2view ); + matrix4_multiply_by_matrix4( object2screen, object2world ); } -inline void ConstructDevice2Object(Matrix4& device2object, const Matrix4& object2world, const Matrix4& world2view, const Matrix4& view2device) -{ - ConstructObject2Device(device2object, object2world, world2view, view2device); - matrix4_full_invert(device2object); +inline void ConstructDevice2Object( Matrix4& device2object, const Matrix4& object2world, const Matrix4& world2view, const Matrix4& view2device ){ + ConstructObject2Device( device2object, object2world, world2view, view2device ); + matrix4_full_invert( device2object ); } //! S = ( Inverse(Object2Screen *post ScaleOf(Object2Screen) ) *post Object2Screen -inline void pivot_scale(Matrix4& scale, const Matrix4& pivot2screen) -{ - Matrix4 pre_scale(g_matrix4_identity); - pre_scale[0] = static_cast(vector3_length(vector4_to_vector3(pivot2screen.x()))); - pre_scale[5] = static_cast(vector3_length(vector4_to_vector3(pivot2screen.y()))); - pre_scale[10] = static_cast(vector3_length(vector4_to_vector3(pivot2screen.z()))); - - scale = pivot2screen; - matrix4_multiply_by_matrix4(scale, pre_scale); - matrix4_full_invert(scale); - matrix4_multiply_by_matrix4(scale, pivot2screen); +inline void pivot_scale( Matrix4& scale, const Matrix4& pivot2screen ){ + Matrix4 pre_scale( g_matrix4_identity ); + pre_scale[0] = static_cast( vector3_length( vector4_to_vector3( pivot2screen.x() ) ) ); + pre_scale[5] = static_cast( vector3_length( vector4_to_vector3( pivot2screen.y() ) ) ); + pre_scale[10] = static_cast( vector3_length( vector4_to_vector3( pivot2screen.z() ) ) ); + + scale = pivot2screen; + matrix4_multiply_by_matrix4( scale, pre_scale ); + matrix4_full_invert( scale ); + matrix4_multiply_by_matrix4( scale, pivot2screen ); } // scale by (inverse) W -inline void pivot_perspective(Matrix4& scale, const Matrix4& pivot2screen) -{ - scale = g_matrix4_identity; - scale[0] = scale[5] = scale[10] = pivot2screen[15]; +inline void pivot_perspective( Matrix4& scale, const Matrix4& pivot2screen ){ + scale = g_matrix4_identity; + scale[0] = scale[5] = scale[10] = pivot2screen[15]; } -inline void ConstructDevice2Manip(Matrix4& device2manip, const Matrix4& object2world, const Matrix4& world2view, const Matrix4& view2device, const Matrix4& device2screen) -{ - Matrix4 pivot2screen; - ConstructObject2Screen(pivot2screen, object2world, world2view, view2device, device2screen); +inline void ConstructDevice2Manip( Matrix4& device2manip, const Matrix4& object2world, const Matrix4& world2view, const Matrix4& view2device, const Matrix4& device2screen ){ + Matrix4 pivot2screen; + ConstructObject2Screen( pivot2screen, object2world, world2view, view2device, device2screen ); - ConstructObject2Device(device2manip, object2world, world2view, view2device); + ConstructObject2Device( device2manip, object2world, world2view, view2device ); - Matrix4 scale; - pivot_scale(scale, pivot2screen); - matrix4_multiply_by_matrix4(device2manip, scale); - pivot_perspective(scale, pivot2screen); - matrix4_multiply_by_matrix4(device2manip, scale); + Matrix4 scale; + pivot_scale( scale, pivot2screen ); + matrix4_multiply_by_matrix4( device2manip, scale ); + pivot_perspective( scale, pivot2screen ); + matrix4_multiply_by_matrix4( device2manip, scale ); - matrix4_full_invert(device2manip); + matrix4_full_invert( device2manip ); } -inline void Pivot2World_worldSpace(Matrix4& manip2world, const Matrix4& pivot2world, const Matrix4& modelview, const Matrix4& projection, const Matrix4& viewport) -{ - manip2world = pivot2world; - - Matrix4 pivot2screen; - ConstructObject2Screen(pivot2screen, pivot2world, modelview, projection, viewport); - - Matrix4 scale; - pivot_scale(scale, pivot2screen); - matrix4_multiply_by_matrix4(manip2world, scale); - pivot_perspective(scale, pivot2screen); - matrix4_multiply_by_matrix4(manip2world, scale); +inline void Pivot2World_worldSpace( Matrix4& manip2world, const Matrix4& pivot2world, const Matrix4& modelview, const Matrix4& projection, const Matrix4& viewport ){ + manip2world = pivot2world; + + Matrix4 pivot2screen; + ConstructObject2Screen( pivot2screen, pivot2world, modelview, projection, viewport ); + + Matrix4 scale; + pivot_scale( scale, pivot2screen ); + matrix4_multiply_by_matrix4( manip2world, scale ); + pivot_perspective( scale, pivot2screen ); + matrix4_multiply_by_matrix4( manip2world, scale ); } -inline void Pivot2World_viewpointSpace(Matrix4& manip2world, Vector3& axis, const Matrix4& pivot2world, const Matrix4& modelview, const Matrix4& projection, const Matrix4& viewport) -{ - manip2world = pivot2world; +inline void Pivot2World_viewpointSpace( Matrix4& manip2world, Vector3& axis, const Matrix4& pivot2world, const Matrix4& modelview, const Matrix4& projection, const Matrix4& viewport ){ + manip2world = pivot2world; - Matrix4 pivot2screen; - ConstructObject2Screen(pivot2screen, pivot2world, modelview, projection, viewport); + Matrix4 pivot2screen; + ConstructObject2Screen( pivot2screen, pivot2world, modelview, projection, viewport ); - Matrix4 scale; - pivot_scale(scale, pivot2screen); - matrix4_multiply_by_matrix4(manip2world, scale); + Matrix4 scale; + pivot_scale( scale, pivot2screen ); + matrix4_multiply_by_matrix4( manip2world, scale ); - billboard_viewpointOriented(scale, pivot2screen); - axis = vector4_to_vector3(scale.z()); - matrix4_multiply_by_matrix4(manip2world, scale); + billboard_viewpointOriented( scale, pivot2screen ); + axis = vector4_to_vector3( scale.z() ); + matrix4_multiply_by_matrix4( manip2world, scale ); - pivot_perspective(scale, pivot2screen); - matrix4_multiply_by_matrix4(manip2world, scale); + pivot_perspective( scale, pivot2screen ); + matrix4_multiply_by_matrix4( manip2world, scale ); } -inline void Pivot2World_viewplaneSpace(Matrix4& manip2world, const Matrix4& pivot2world, const Matrix4& modelview, const Matrix4& projection, const Matrix4& viewport) -{ - manip2world = pivot2world; +inline void Pivot2World_viewplaneSpace( Matrix4& manip2world, const Matrix4& pivot2world, const Matrix4& modelview, const Matrix4& projection, const Matrix4& viewport ){ + manip2world = pivot2world; - Matrix4 pivot2screen; - ConstructObject2Screen(pivot2screen, pivot2world, modelview, projection, viewport); + Matrix4 pivot2screen; + ConstructObject2Screen( pivot2screen, pivot2world, modelview, projection, viewport ); - Matrix4 scale; - pivot_scale(scale, pivot2screen); - matrix4_multiply_by_matrix4(manip2world, scale); + Matrix4 scale; + pivot_scale( scale, pivot2screen ); + matrix4_multiply_by_matrix4( manip2world, scale ); - billboard_viewplaneOriented(scale, pivot2screen); - matrix4_multiply_by_matrix4(manip2world, scale); + billboard_viewplaneOriented( scale, pivot2screen ); + matrix4_multiply_by_matrix4( manip2world, scale ); - pivot_perspective(scale, pivot2screen); - matrix4_multiply_by_matrix4(manip2world, scale); + pivot_perspective( scale, pivot2screen ); + matrix4_multiply_by_matrix4( manip2world, scale ); } @@ -235,59 +224,59 @@ inline void Pivot2World_viewplaneSpace(Matrix4& manip2world, const Matrix4& pivo #include "cullable.h" #include "render.h" -const Colour4b g_colour_x(255, 0, 0, 255); -const Colour4b g_colour_y(0, 255, 0, 255); -const Colour4b g_colour_z(0, 0, 255, 255); +const Colour4b g_colour_x( 255, 0, 0, 255 ); +const Colour4b g_colour_y( 0, 255, 0, 255 ); +const Colour4b g_colour_z( 0, 0, 255, 255 ); class Shader; class RenderablePivot : public OpenGLRenderable { - VertexBuffer m_vertices; +VertexBuffer m_vertices; public: - mutable Matrix4 m_localToWorld; - typedef Static StaticShader; - static Shader* getShader() - { - return StaticShader::instance(); - } - - RenderablePivot() - { - m_vertices.reserve(6); - - m_vertices.push_back(PointVertex(Vertex3f(0, 0, 0), g_colour_x)); - m_vertices.push_back(PointVertex(Vertex3f(16, 0, 0), g_colour_x)); - - m_vertices.push_back(PointVertex(Vertex3f(0, 0, 0), g_colour_y)); - m_vertices.push_back(PointVertex(Vertex3f(0, 16, 0), g_colour_y)); - - m_vertices.push_back(PointVertex(Vertex3f(0, 0, 0), g_colour_z)); - m_vertices.push_back(PointVertex(Vertex3f(0, 0, 16), g_colour_z)); - } - - void render(RenderStateFlags state) const - { - if(m_vertices.size() == 0) return; - if(m_vertices.data() == 0) return; - glVertexPointer(3, GL_FLOAT, sizeof(PointVertex), &m_vertices.data()->vertex); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(PointVertex), &m_vertices.data()->colour); - glDrawArrays(GL_LINES, 0, m_vertices.size()); - } - - void render(Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld) const - { - renderer.PushState(); - - Pivot2World_worldSpace(m_localToWorld, localToWorld, volume.GetModelview(), volume.GetProjection(), volume.GetViewport()); - - renderer.Highlight(Renderer::ePrimitive, false); - renderer.SetState(getShader(), Renderer::eWireframeOnly); - renderer.SetState(getShader(), Renderer::eFullMaterials); - renderer.addRenderable(*this, m_localToWorld); - - renderer.PopState(); - } +mutable Matrix4 m_localToWorld; +typedef Static StaticShader; +static Shader* getShader(){ + return StaticShader::instance(); +} + +RenderablePivot(){ + m_vertices.reserve( 6 ); + + m_vertices.push_back( PointVertex( Vertex3f( 0, 0, 0 ), g_colour_x ) ); + m_vertices.push_back( PointVertex( Vertex3f( 16, 0, 0 ), g_colour_x ) ); + + m_vertices.push_back( PointVertex( Vertex3f( 0, 0, 0 ), g_colour_y ) ); + m_vertices.push_back( PointVertex( Vertex3f( 0, 16, 0 ), g_colour_y ) ); + + m_vertices.push_back( PointVertex( Vertex3f( 0, 0, 0 ), g_colour_z ) ); + m_vertices.push_back( PointVertex( Vertex3f( 0, 0, 16 ), g_colour_z ) ); +} + +void render( RenderStateFlags state ) const { + if ( m_vertices.size() == 0 ) { + return; + } + if ( m_vertices.data() == 0 ) { + return; + } + glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_vertices.data()->vertex ); + glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_vertices.data()->colour ); + glDrawArrays( GL_LINES, 0, m_vertices.size() ); +} + +void render( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const { + renderer.PushState(); + + Pivot2World_worldSpace( m_localToWorld, localToWorld, volume.GetModelview(), volume.GetProjection(), volume.GetViewport() ); + + renderer.Highlight( Renderer::ePrimitive, false ); + renderer.SetState( getShader(), Renderer::eWireframeOnly ); + renderer.SetState( getShader(), Renderer::eFullMaterials ); + renderer.addRenderable( *this, m_localToWorld ); + + renderer.PopState(); +} };