Equalizer 1.0
|
00001 00002 /* Copyright (c) 2007, Tobias Wolf <twolf@access.unizh.ch> 00003 * Copyright (c) 2008, Stefan Eilemann <eile@equalizergraphics.com> 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * - Redistributions of source code must retain the above copyright notice, this 00009 * list of conditions and the following disclaimer. 00010 * - Redistributions in binary form must reproduce the above copyright notice, 00011 * this list of conditions and the following disclaimer in the documentation 00012 * and/or other materials provided with the distribution. 00013 * - Neither the name of Eyescale Software GmbH nor the names of its 00014 * contributors may be used to endorse or promote products derived from this 00015 * software without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00018 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00021 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00022 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00023 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00024 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00025 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00026 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00027 * POSSIBILITY OF SUCH DAMAGE. 00028 00029 00030 Implementation of the VertexBufferNode class. 00031 */ 00032 00033 00034 #include "vertexBufferNode.h" 00035 #include "vertexBufferLeaf.h" 00036 #include "vertexBufferState.h" 00037 #include "vertexData.h" 00038 #include <set> 00039 00040 00041 using namespace std; 00042 00043 namespace mesh 00044 { 00045 00046 inline static bool _subdivide( const Index length, const size_t depth ) 00047 { 00048 return ( length / 2 > LEAF_SIZE ) || ( depth < 3 && length > 1 ); 00049 } 00050 00051 /* Continue kd-tree setup, create intermediary or leaf nodes as required. */ 00052 void VertexBufferNode::setupTree( VertexData& data, const Index start, 00053 const Index length, const Axis axis, 00054 const size_t depth, 00055 VertexBufferData& globalData ) 00056 { 00057 #ifndef NDEBUG 00058 MESHINFO << "setupTree" 00059 << "( " << start << ", " << length << ", " << axis << ", " 00060 << depth << " )." << endl; 00061 #endif 00062 00063 data.sort( start, length, axis ); 00064 const Index median = start + ( length / 2 ); 00065 00066 // left child will include elements smaller than the median 00067 const Index leftLength = length / 2; 00068 const bool subdivideLeft = _subdivide( leftLength, depth ); 00069 00070 if( subdivideLeft ) 00071 _left = new VertexBufferNode; 00072 else 00073 _left = new VertexBufferLeaf( globalData ); 00074 00075 // right child will include elements equal to or greater than the median 00076 const Index rightLength = ( length + 1 ) / 2; 00077 const bool subdivideRight = _subdivide( rightLength, depth ); 00078 00079 if( subdivideRight ) 00080 _right = new VertexBufferNode; 00081 else 00082 _right = new VertexBufferLeaf( globalData ); 00083 00084 // move to next axis and continue contruction in the child nodes 00085 const Axis newAxisLeft = subdivideLeft ? 00086 data.getLongestAxis( start , leftLength ) : AXIS_X; 00087 00088 const Axis newAxisRight = subdivideRight ? 00089 data.getLongestAxis( median, rightLength ) : AXIS_X; 00090 00091 static_cast< VertexBufferNode* > 00092 ( _left )->setupTree( data, start, leftLength, newAxisLeft, depth+1, 00093 globalData ); 00094 static_cast< VertexBufferNode* > 00095 ( _right )->setupTree( data, median, rightLength, newAxisRight, depth+1, 00096 globalData ); 00097 00098 } 00099 00100 00101 /* Compute the bounding sphere from the children's bounding spheres. */ 00102 const BoundingSphere& VertexBufferNode::updateBoundingSphere() 00103 { 00104 // take the bounding spheres returned by the children 00105 const BoundingSphere& sphere1 = _left->updateBoundingSphere(); 00106 const BoundingSphere& sphere2 = _right->updateBoundingSphere(); 00107 00108 // compute enclosing sphere 00109 const Vertex center1( sphere1.array ); 00110 const Vertex center2( sphere2.array ); 00111 Vertex c1ToC2 = center2 - center1; 00112 c1ToC2.normalize(); 00113 00114 const Vertex outer1 = center1 - c1ToC2 * sphere1.w(); 00115 const Vertex outer2 = center2 + c1ToC2 * sphere2.w(); 00116 00117 Vertex vertexBoundingSphere = Vertex( outer1 + outer2 ) * 0.5f; 00118 _boundingSphere.x() = vertexBoundingSphere.x(); 00119 _boundingSphere.y() = vertexBoundingSphere.y(); 00120 _boundingSphere.z() = vertexBoundingSphere.z(); 00121 _boundingSphere.w() = Vertex( outer1 - outer2 ).length() * 0.5f; 00122 00123 #ifndef NDEBUG 00124 MESHINFO << "updateBoundingSphere" << "( " << _boundingSphere << " )." 00125 << endl; 00126 #endif 00127 00128 return _boundingSphere; 00129 } 00130 00131 00132 /* Compute the range from the children's ranges. */ 00133 void VertexBufferNode::updateRange() 00134 { 00135 // update the children's ranges 00136 static_cast< VertexBufferNode* >( _left )->updateRange(); 00137 static_cast< VertexBufferNode* >( _right )->updateRange(); 00138 00139 // set node range to min/max of the children's ranges 00140 _range[0] = min( _left->getRange()[0], _right->getRange()[0] ); 00141 _range[1] = max( _left->getRange()[1], _right->getRange()[1] ); 00142 00143 #ifndef NDEBUG 00144 MESHINFO << "updateRange" << "( " << _range[0] << ", " << _range[1] 00145 << " )." << endl; 00146 #endif 00147 } 00148 00149 00150 /* Render the node by rendering the children. */ 00151 void VertexBufferNode::render( VertexBufferState& state ) const 00152 { 00153 if ( state.stopRendering( )) 00154 return; 00155 00156 _left->render( state ); 00157 _right->render( state ); 00158 } 00159 00160 00161 /* Read node from memory and continue with remaining nodes. */ 00162 void VertexBufferNode::fromMemory( char** addr, VertexBufferData& globalData ) 00163 { 00164 // read node itself 00165 size_t nodeType; 00166 memRead( reinterpret_cast< char* >( &nodeType ), addr, sizeof( size_t ) ); 00167 if( nodeType != NODE_TYPE ) 00168 throw MeshException( "Error reading binary file. Expected a regular " 00169 "node, but found something else instead." ); 00170 VertexBufferBase::fromMemory( addr, globalData ); 00171 00172 // read left child (peek ahead) 00173 memRead( reinterpret_cast< char* >( &nodeType ), addr, sizeof( size_t ) ); 00174 if( nodeType != NODE_TYPE && nodeType != LEAF_TYPE ) 00175 throw MeshException( "Error reading binary file. Expected either a " 00176 "regular or a leaf node, but found neither." ); 00177 *addr -= sizeof( size_t ); 00178 if( nodeType == NODE_TYPE ) 00179 _left = new VertexBufferNode; 00180 else 00181 _left = new VertexBufferLeaf( globalData ); 00182 static_cast< VertexBufferNode* >( _left )->fromMemory( addr, globalData ); 00183 00184 // read right child (peek ahead) 00185 memRead( reinterpret_cast< char* >( &nodeType ), addr, sizeof( size_t ) ); 00186 if( nodeType != NODE_TYPE && nodeType != LEAF_TYPE ) 00187 throw MeshException( "Error reading binary file. Expected either a " 00188 "regular or a leaf node, but found neither." ); 00189 *addr -= sizeof( size_t ); 00190 if( nodeType == NODE_TYPE ) 00191 _right = new VertexBufferNode; 00192 else 00193 _right = new VertexBufferLeaf( globalData ); 00194 static_cast< VertexBufferNode* >( _right )->fromMemory( addr, globalData ); 00195 } 00196 00197 00198 /* Write node to output stream and continue with remaining nodes. */ 00199 void VertexBufferNode::toStream( std::ostream& os ) 00200 { 00201 size_t nodeType = NODE_TYPE; 00202 os.write( reinterpret_cast< char* >( &nodeType ), sizeof( size_t ) ); 00203 VertexBufferBase::toStream( os ); 00204 static_cast< VertexBufferNode* >( _left )->toStream( os ); 00205 static_cast< VertexBufferNode* >( _right )->toStream( os ); 00206 } 00207 00208 00209 /* Destructor, clears up children as well. */ 00210 VertexBufferNode::~VertexBufferNode() 00211 { 00212 delete static_cast< VertexBufferNode* >( _left ); 00213 delete static_cast< VertexBufferNode* >( _right ); 00214 } 00215 }