pivot.h

Go to the documentation of this file.
00001 /*
00002  Copyright (C) 2001-2006, William Joseph.
00003  All Rights Reserved.
00004 
00005  This file is part of GtkRadiant.
00006 
00007  GtkRadiant is free software; you can redistribute it and/or modify
00008  it under the terms of the GNU General Public License as published by
00009  the Free Software Foundation; either version 2 of the License, or
00010  (at your option) any later version.
00011 
00012  GtkRadiant is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU General Public License for more details.
00016 
00017  You should have received a copy of the GNU General Public License
00018  along with GtkRadiant; if not, write to the Free Software
00019  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020  */
00021 
00022 #if !defined(INCLUDED_PIVOT_H)
00023 #define INCLUDED_PIVOT_H
00024 
00025 #include "math/matrix.h"
00026 
00027 inline void billboard_viewplaneOriented (Matrix4& rotation, const Matrix4& world2screen)
00028 {
00029     rotation = g_matrix4_identity;
00030     Vector3 x(world2screen.x().getVector3().getNormalised());
00031     Vector3 y(world2screen.y().getVector3().getNormalised());
00032     Vector3 z(world2screen.z().getVector3().getNormalised());
00033     rotation.y().getVector3() = Vector3(x.y(), y.y(), z.y());
00034     rotation.z().getVector3() = -Vector3(x.z(), y.z(), z.z());
00035     rotation.x().getVector3() = rotation.y().getVector3().crossProduct(rotation.z().getVector3()).getNormalised();
00036     rotation.y().getVector3() = rotation.z().getVector3().crossProduct(rotation.x().getVector3());
00037 
00038 }
00039 
00040 inline void billboard_viewpointOriented (Matrix4& rotation, const Matrix4& world2screen)
00041 {
00042     Matrix4 screen2world(matrix4_full_inverse(world2screen));
00043 
00044     rotation = g_matrix4_identity;
00045     rotation.y().getVector3() = screen2world.y().getVector3().getNormalised();
00046     rotation.z().getVector3() = -screen2world.z().getVector3().getNormalised();
00047     rotation.x().getVector3() = rotation.y().getVector3().crossProduct(rotation.z().getVector3()).getNormalised();
00048     rotation.y().getVector3() = rotation.z().getVector3().crossProduct(rotation.x().getVector3());
00049 }
00050 
00051 inline void ConstructObject2Screen (Matrix4& object2screen, const Matrix4& object2world, const Matrix4& world2view,
00052         const Matrix4& view2device, const Matrix4& device2screen)
00053 {
00054     object2screen = device2screen;
00055     matrix4_multiply_by_matrix4(object2screen, view2device);
00056     matrix4_multiply_by_matrix4(object2screen, world2view);
00057     matrix4_multiply_by_matrix4(object2screen, object2world);
00058 }
00059 
00060 inline void ConstructObject2Device (Matrix4& object2screen, const Matrix4& object2world, const Matrix4& world2view,
00061         const Matrix4& view2device)
00062 {
00063     object2screen = view2device;
00064     matrix4_multiply_by_matrix4(object2screen, world2view);
00065     matrix4_multiply_by_matrix4(object2screen, object2world);
00066 }
00067 
00068 inline void ConstructDevice2Object (Matrix4& device2object, const Matrix4& object2world, const Matrix4& world2view,
00069         const Matrix4& view2device)
00070 {
00071     ConstructObject2Device(device2object, object2world, world2view, view2device);
00072     matrix4_full_invert(device2object);
00073 }
00074 
00076 inline void pivot_scale (Matrix4& scale, const Matrix4& pivot2screen)
00077 {
00078     Matrix4 pre_scale(g_matrix4_identity);
00079     pre_scale[0] = static_cast<float> (pivot2screen.x().getVector3().getLength());
00080     pre_scale[5] = static_cast<float> (pivot2screen.y().getVector3().getLength());
00081     pre_scale[10] = static_cast<float> (pivot2screen.z().getVector3().getLength());
00082 
00083     scale = pivot2screen;
00084     matrix4_multiply_by_matrix4(scale, pre_scale);
00085     matrix4_full_invert(scale);
00086     matrix4_multiply_by_matrix4(scale, pivot2screen);
00087 }
00088 
00089 // scale by (inverse) W
00090 inline void pivot_perspective (Matrix4& scale, const Matrix4& pivot2screen)
00091 {
00092     scale = g_matrix4_identity;
00093     scale[0] = scale[5] = scale[10] = pivot2screen[15];
00094 }
00095 
00096 inline void ConstructDevice2Manip (Matrix4& device2manip, const Matrix4& object2world, const Matrix4& world2view,
00097         const Matrix4& view2device, const Matrix4& device2screen)
00098 {
00099     Matrix4 pivot2screen;
00100     ConstructObject2Screen(pivot2screen, object2world, world2view, view2device, device2screen);
00101 
00102     ConstructObject2Device(device2manip, object2world, world2view, view2device);
00103 
00104     Matrix4 scale;
00105     pivot_scale(scale, pivot2screen);
00106     matrix4_multiply_by_matrix4(device2manip, scale);
00107     pivot_perspective(scale, pivot2screen);
00108     matrix4_multiply_by_matrix4(device2manip, scale);
00109 
00110     matrix4_full_invert(device2manip);
00111 }
00112 
00113 inline void Pivot2World_worldSpace (Matrix4& manip2world, const Matrix4& pivot2world, const Matrix4& modelview,
00114         const Matrix4& projection, const Matrix4& viewport)
00115 {
00116     manip2world = pivot2world;
00117 
00118     Matrix4 pivot2screen;
00119     ConstructObject2Screen(pivot2screen, pivot2world, modelview, projection, viewport);
00120 
00121     Matrix4 scale;
00122     pivot_scale(scale, pivot2screen);
00123     matrix4_multiply_by_matrix4(manip2world, scale);
00124     pivot_perspective(scale, pivot2screen);
00125     matrix4_multiply_by_matrix4(manip2world, scale);
00126 }
00127 
00128 inline void Pivot2World_viewpointSpace (Matrix4& manip2world, Vector3& axis, const Matrix4& pivot2world,
00129         const Matrix4& modelview, const Matrix4& projection, const Matrix4& viewport)
00130 {
00131     manip2world = pivot2world;
00132 
00133     Matrix4 pivot2screen;
00134     ConstructObject2Screen(pivot2screen, pivot2world, modelview, projection, viewport);
00135 
00136     Matrix4 scale;
00137     pivot_scale(scale, pivot2screen);
00138     matrix4_multiply_by_matrix4(manip2world, scale);
00139 
00140     billboard_viewpointOriented(scale, pivot2screen);
00141     axis = scale.z().getVector3();
00142     matrix4_multiply_by_matrix4(manip2world, scale);
00143 
00144     pivot_perspective(scale, pivot2screen);
00145     matrix4_multiply_by_matrix4(manip2world, scale);
00146 }
00147 
00148 inline void Pivot2World_viewplaneSpace (Matrix4& manip2world, const Matrix4& pivot2world, const Matrix4& modelview,
00149         const Matrix4& projection, const Matrix4& viewport)
00150 {
00151     manip2world = pivot2world;
00152 
00153     Matrix4 pivot2screen;
00154     ConstructObject2Screen(pivot2screen, pivot2world, modelview, projection, viewport);
00155 
00156     Matrix4 scale;
00157     pivot_scale(scale, pivot2screen);
00158     matrix4_multiply_by_matrix4(manip2world, scale);
00159 
00160     billboard_viewplaneOriented(scale, pivot2screen);
00161     matrix4_multiply_by_matrix4(manip2world, scale);
00162 
00163     pivot_perspective(scale, pivot2screen);
00164     matrix4_multiply_by_matrix4(manip2world, scale);
00165 }
00166 
00167 #include "renderable.h"
00168 #include "cullable.h"
00169 #include "render.h"
00170 
00171 const Colour4b g_colour_x(255, 0, 0, 255);
00172 const Colour4b g_colour_y(0, 255, 0, 255);
00173 const Colour4b g_colour_z(0, 0, 255, 255);
00174 
00175 class Shader;
00176 
00177 class RenderablePivot: public OpenGLRenderable
00178 {
00179         VertexBuffer<PointVertex> m_vertices;
00180     public:
00181         mutable Matrix4 m_localToWorld;
00182         typedef Static<Shader*> StaticShader;
00183         static Shader* getShader ()
00184         {
00185             return StaticShader::instance();
00186         }
00187 
00188         RenderablePivot ()
00189         {
00190             m_vertices.reserve(6);
00191 
00192             m_vertices.push_back(PointVertex(Vertex3f(0, 0, 0), g_colour_x));
00193             m_vertices.push_back(PointVertex(Vertex3f(16, 0, 0), g_colour_x));
00194 
00195             m_vertices.push_back(PointVertex(Vertex3f(0, 0, 0), g_colour_y));
00196             m_vertices.push_back(PointVertex(Vertex3f(0, 16, 0), g_colour_y));
00197 
00198             m_vertices.push_back(PointVertex(Vertex3f(0, 0, 0), g_colour_z));
00199             m_vertices.push_back(PointVertex(Vertex3f(0, 0, 16), g_colour_z));
00200         }
00201 
00202         void render (RenderStateFlags state) const
00203         {
00204             if (m_vertices.size() == 0)
00205                 return;
00206             if (m_vertices.data() == 0)
00207                 return;
00208             glVertexPointer(3, GL_FLOAT, sizeof(PointVertex), &m_vertices.data()->vertex);
00209             glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(PointVertex), &m_vertices.data()->colour);
00210             glDrawArrays(GL_LINES, 0, m_vertices.size());
00211         }
00212 
00213         void render (Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld) const
00214         {
00215             renderer.PushState();
00216 
00217             Pivot2World_worldSpace(m_localToWorld, localToWorld, volume.GetModelview(), volume.GetProjection(),
00218                     volume.GetViewport());
00219 
00220             renderer.Highlight(Renderer::ePrimitive, false);
00221             renderer.SetState(getShader(), Renderer::eWireframeOnly);
00222             renderer.SetState(getShader(), Renderer::eFullMaterials);
00223             renderer.addRenderable(*this, m_localToWorld);
00224 
00225             renderer.PopState();
00226         }
00227 };
00228 
00229 #endif

Generated by  doxygen 1.6.2