Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

OgreOctreeCamera.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002 octreecamera.cpp  -  description
00003 -------------------
00004 begin                : Fri Sep 27 2002
00005 copyright            : (C) 2002 by Jon Anderson
00006 email                : janders@users.sf.net
00007 ***************************************************************************/
00008 
00009 /***************************************************************************
00010 *                                                                         *
00011 *   This program is free software; you can redistribute it and/or modify  *
00012 *   it under the terms of the GNU Lesser General Public License as        *
00013 *   published by the Free Software Foundation; either version 2 of the    * 
00014 *   License, or (at your option) any later version.                       *
00015 *                                                                         *
00016 ***************************************************************************/
00017 
00018 #include <OgreMath.h>
00019 #include <OgreAxisAlignedBox.h>
00020 #include <OgreRoot.h>
00021 
00022 #include <OgreOctreeCamera.h>
00023 
00024 namespace Ogre
00025 {
00026 #define POSITION_BINDING 0
00027 #define COLOUR_BINDING 1
00028 
00029 unsigned long red = 0xFF0000FF;
00030 
00031 unsigned short OctreeCamera::mIndexes[ 24 ] = {0, 1, 1, 2, 2, 3, 3, 0,       //back
00032         0, 6, 6, 5, 5, 1,             //left
00033         3, 7, 7, 4, 4, 2,             //right
00034         6, 7, 5, 4 };          //front
00035 
00036 unsigned long OctreeCamera::mColors[ 8 ] = {red, red, red, red, red, red, red, red};
00037 
00038 OctreeCamera::OctreeCamera( const String& name, SceneManager* sm ) : Camera( name, sm )
00039 {
00040     mMaterial = sm->getMaterial("BaseWhite");
00041 
00042     mVertexData = new VertexData;
00043     mVertexData->vertexStart = 0;
00044     mVertexData->vertexCount = 8;
00045 
00046     mIndexData = new IndexData;
00047     mIndexData->indexStart = 0;
00048     mIndexData->indexCount = 24;
00049 
00050     VertexDeclaration* decl = mVertexData->vertexDeclaration;
00051     VertexBufferBinding* bind = mVertexData->vertexBufferBinding;
00052 
00053     decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION);
00054     decl->addElement(COLOUR_BINDING, 0, VET_COLOUR, VES_DIFFUSE);
00055 
00056     HardwareVertexBufferSharedPtr vbuf =
00057         HardwareBufferManager::getSingleton().createVertexBuffer(
00058             decl->getVertexSize(POSITION_BINDING),
00059             mVertexData->vertexCount,
00060             HardwareBuffer::HBU_STATIC_WRITE_ONLY);
00061 
00062     bind->setBinding(POSITION_BINDING, vbuf);
00063 
00064     mIndexData->indexBuffer = 
00065         HardwareBufferManager::getSingleton().createIndexBuffer(
00066             HardwareIndexBuffer::IT_16BIT,
00067             24, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
00068                                                                       
00069 }
00070 
00071 OctreeCamera::~OctreeCamera()
00072 {
00073     if(mVertexData)
00074         delete mVertexData;
00075     if(mIndexData)
00076         delete mIndexData;
00077 }
00078 
00079 OctreeCamera::Visibility OctreeCamera::getVisibility( const AxisAlignedBox &bound )
00080 {
00081 
00082     // Null boxes always invisible
00083     if ( bound.isNull() )
00084         return NONE;
00085 
00086     // Make any pending updates to the calculated frustum
00087     updateView();
00088 
00089     // Get corners of the box
00090     const Vector3* pCorners = bound.getAllCorners();
00091 
00092     // For each plane, see if all points are on the negative side
00093     // If so, object is not visible.
00094     // If one or more are, it's partial.
00095     // If all aren't, full
00096 
00097     int corners[ 8 ] = {0, 4, 3, 5, 2, 6, 1, 7};
00098 
00099     int planes[ 6 ] = {FRUSTUM_PLANE_TOP, FRUSTUM_PLANE_BOTTOM,
00100                        FRUSTUM_PLANE_LEFT, FRUSTUM_PLANE_RIGHT,
00101                        FRUSTUM_PLANE_FAR, FRUSTUM_PLANE_NEAR };
00102 
00103     bool all_inside = true;
00104 
00105     for ( int plane = 0; plane < 6; ++plane )
00106     {
00107 
00108         bool all_outside = true;
00109 
00110         float distance = 0;
00111 
00112         for ( int corner = 0; corner < 8; ++corner )
00113         {
00114             distance = mFrustumPlanes[ planes[ plane ] ].getDistance( pCorners[ corners[ corner ] ] );
00115             all_outside = all_outside && ( distance < 0 );
00116             all_inside = all_inside && ( distance >= 0 );
00117 
00118             if ( !all_outside && !all_inside )
00119                 break;
00120         }
00121 
00122         if ( all_outside )
00123             return NONE;
00124     }
00125 
00126     if ( all_inside )
00127         return FULL;
00128     else
00129         return PARTIAL;
00130 
00131 }
00132 
00133 void OctreeCamera::getRenderOperation( RenderOperation& op )
00134 {
00135     std::cerr << "OctreeCamera::getRenderOperation\n";
00136 
00137     Real * r = mCorners;
00138     //could also project pts using inverse of 4x4 Projection matrix, but no inverse function on that.
00139     /*
00140     Matrix4 invP =getProjectionMatrix().Inverse();
00141 
00142     Vector3 f1(-1,-1,-1); f1 = f1*invP;
00143     Vector3 f2(-1, 1,-1); f2 = f2*invP;
00144     Vector3 f3( 1, 1,-1); f3 = f3*invP;
00145     Vector3 f4( 1,-1,-1); f4 = f4*invP;
00146 
00147     Vector3 b1(-1,-1,1); b1 = b1*invP;
00148     Vector3 b2(-1, 1,1); b2 = b2*invP;
00149     Vector3 b3( 1, 1,1); b3 = b3*invP;
00150     Vector3 b4( 1,-1,1); b4 = b4*invP;
00151     */
00152     _getCorner( r, FRUSTUM_PLANE_FAR, FRUSTUM_PLANE_LEFT, FRUSTUM_PLANE_BOTTOM ); r += 3;
00153     _getCorner( r, FRUSTUM_PLANE_FAR, FRUSTUM_PLANE_LEFT, FRUSTUM_PLANE_TOP ); r += 3;
00154     _getCorner( r, FRUSTUM_PLANE_FAR, FRUSTUM_PLANE_RIGHT, FRUSTUM_PLANE_TOP ); r += 3;
00155     _getCorner( r, FRUSTUM_PLANE_FAR, FRUSTUM_PLANE_RIGHT, FRUSTUM_PLANE_BOTTOM ); r += 3;
00156 
00157     _getCorner( r, FRUSTUM_PLANE_NEAR, FRUSTUM_PLANE_RIGHT, FRUSTUM_PLANE_TOP ); r += 3;
00158     _getCorner( r, FRUSTUM_PLANE_NEAR, FRUSTUM_PLANE_LEFT, FRUSTUM_PLANE_TOP ); r += 3;
00159     _getCorner( r, FRUSTUM_PLANE_NEAR, FRUSTUM_PLANE_LEFT, FRUSTUM_PLANE_BOTTOM ); r += 3;
00160     _getCorner( r, FRUSTUM_PLANE_NEAR, FRUSTUM_PLANE_RIGHT, FRUSTUM_PLANE_BOTTOM );
00161 
00162     updateView();
00163 
00164     HardwareVertexBufferSharedPtr vbuf = 
00165         mVertexData->vertexBufferBinding->getBuffer(POSITION_BINDING);
00166 
00167     vbuf->writeData(0, 8 * sizeof(Real), mCorners);
00168 
00169     vbuf = mVertexData->vertexBufferBinding->getBuffer(COLOUR_BINDING);
00170     vbuf->writeData(0, 8 * sizeof(RGBA), mColors);
00171 
00172     mIndexData->indexBuffer->writeData(0, 24 * sizeof(unsigned short), mIndexes);
00173 
00174     op.useIndexes = true;
00175     op.operationType = RenderOperation::OT_LINE_LIST;
00176     op.vertexData = mVertexData;
00177     op.indexData = mIndexData;
00178 
00179     /* 
00180     rend.useIndexes = true;
00181     rend.numTextureCoordSets = 0; // no textures
00182     rend.vertexOptions = LegacyRenderOperation::VO_DIFFUSE_COLOURS;
00183     rend.numVertices = 8;
00184     rend.numIndexes = 24;
00185 
00186     rend.pVertices = mCorners;
00187     rend.pIndexes = mIndexes;
00188     rend.pDiffuseColour = mColors;
00189     */
00190 
00191 }
00192 
00193 void OctreeCamera::_getCorner( Real *r, FrustumPlane pp1, FrustumPlane pp2, FrustumPlane pp3 )
00194 {
00195     //intersect the three planes to get a point.
00196     //this could be faster since we know what Z is, but showing the camera is only a debug tool...
00197 
00198 
00199     Plane p1 = mFrustumPlanes[ pp1 ];
00200     Plane p2 = mFrustumPlanes[ pp2 ];
00201     Plane p3 = mFrustumPlanes[ pp3 ];
00202 
00203     Matrix3 mdet ( p1.normal.x , p1.normal.y , p1.normal.z ,
00204                    p2.normal.x , p2.normal.y , p2.normal.z ,
00205                    p3.normal.x , p3.normal.y , p3.normal.z );
00206 
00207     float det = mdet.Determinant ();
00208 
00209     if ( det == 0 ) return ; //some planes are parallel.
00210 
00211     Matrix3 mx ( -p1.d , p1.normal.y , p1.normal.z,
00212                  -p2.d, p2.normal.y , p2.normal.z,
00213                  -p3.d, p3.normal.y , p3.normal.z );
00214 
00215     float xdet = mx.Determinant();
00216 
00217     Matrix3 my ( p1.normal.x, -p1.d, p1.normal.z,
00218                  p2.normal.x, -p2.d, p2.normal.z,
00219                  p3.normal.x, -p3.d, p3.normal.z );
00220 
00221     float ydet = my.Determinant ();
00222 
00223     Matrix3 mz ( p1.normal.x, p1.normal.y, -p1.d,
00224                  p2.normal.x, p2.normal.y, -p2.d,
00225                  p3.normal.x, p3.normal.y, -p3.d );
00226 
00227     float zdet = mz.Determinant ();
00228 
00229     r[ 0 ] = xdet / det;
00230 
00231     r[ 1 ] = ydet / det;
00232 
00233     r[ 2 ] = zdet / det;
00234 
00235 }
00236 
00237 Real OctreeCamera::getSquaredViewDepth(const Camera* cam) const
00238 {
00239     Vector3 dist = cam->getDerivedPosition() - this->getDerivedPosition();
00240     return dist.squaredLength();
00241 }
00242 Material* OctreeCamera::getMaterial(void) const
00243 {
00244     return mMaterial;
00245 }
00246 
00247 void OctreeCamera::getWorldTransforms(Matrix4* xform) const
00248 {
00249     xform[0] = Matrix4::IDENTITY;
00250 }
00251 
00252 const Quaternion& OctreeCamera::getWorldOrientation(void) const
00253 {
00254     return Quaternion::IDENTITY;
00255 }
00256 const Vector3& OctreeCamera::getWorldPosition(void) const
00257 {
00258     return Vector3::ZERO;
00259 }
00260 const LightList& OctreeCamera::getLights(void) const
00261 {
00262     // N/A
00263     static LightList ll;
00264     return ll;
00265 }
00266 
00267 }
00268 
00269 
00270 
00271 

Copyright © 2002-2003 by The OGRE Team
Last modified Wed Jan 21 00:10:19 2004