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