Equalizer  1.6.1
seqPly/vertexBufferDist.cpp
1 
2 /* Copyright (c) 2008-2013, Stefan Eilemann <eile@equalizergraphics.com>
3  * 2010, Cedric Stalder <cedric.stalder@gmail.com>
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * - Redistributions of source code must retain the above copyright notice, this
9  * list of conditions and the following disclaimer.
10  * - Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  * - Neither the name of Eyescale Software GmbH nor the names of its
14  * contributors may be used to endorse or promote products derived from this
15  * software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28 
29  *
30  * co::Object to distribute a model. Has a VertexBufferBase node.
31  */
32 
33 #include "vertexBufferDist.h"
34 
35 #include "vertexBufferLeaf.h"
36 
37 namespace eqPly
38 {
39 
40 VertexBufferDist::VertexBufferDist()
41  : _root( 0 )
42  , _node( 0 )
43  , _left( 0 )
44  , _right( 0 )
45  , _isRoot( false )
46 {}
47 
48 VertexBufferDist::VertexBufferDist( const mesh::VertexBufferRoot* root )
49  : _root( root )
50  , _node( root )
51  , _left( 0 )
52  , _right( 0 )
53  , _isRoot( true )
54 {
55  if( root->getLeft( ))
56  _left = new VertexBufferDist( root, root->getLeft( ));
57 
58  if( root->getRight( ))
59  _right = new VertexBufferDist( root, root->getRight( ));
60 }
61 
62 VertexBufferDist::VertexBufferDist( const mesh::VertexBufferRoot* root,
63  const mesh::VertexBufferBase* node )
64  : _root( root )
65  , _node( node )
66  , _left( 0 )
67  , _right( 0 )
68  , _isRoot( false )
69 {
70  if( !node )
71  return;
72 
73  if( node->getLeft( ))
74  _left = new VertexBufferDist( root, node->getLeft( ));
75 
76  if( node->getRight( ))
77  _right = new VertexBufferDist( root, node->getRight( ));
78 }
79 
80 VertexBufferDist::~VertexBufferDist()
81 {
82  delete _left;
83  _left = 0;
84  delete _right;
85  _right = 0;
86 }
87 
88 void VertexBufferDist::registerTree( co::LocalNodePtr node )
89 {
90  LBASSERT( !isAttached() );
91  LBCHECK( node->registerObject( this ));
92 
93  if( _left )
94  _left->registerTree( node );
95 
96  if( _right )
97  _right->registerTree( node );
98 }
99 
100 void VertexBufferDist::deregisterTree()
101 {
102  LBASSERT( isAttached() );
103  LBASSERT( isMaster( ));
104 
105  getLocalNode()->deregisterObject( this );
106 
107  if( _left )
108  _left->deregisterTree();
109  if( _right )
110  _right->deregisterTree();
111 }
112 
113 mesh::VertexBufferRoot* VertexBufferDist::loadModel( co::NodePtr master,
114  co::LocalNodePtr localNode,
115  const eq::uint128_t& modelID )
116 {
117  LBASSERT( !_root && !_node );
118 
119  const uint32_t req = localNode->mapObjectNB( this, modelID,
120  co::VERSION_OLDEST, master );
121  if( !localNode->mapObjectSync( req ))
122  {
123  LBWARN << "Mapping of model failed" << std::endl;
124  return 0;
125  }
126 
127  _unmapTree();
128  return const_cast< mesh::VertexBufferRoot* >( _root );
129 }
130 
131 void VertexBufferDist::_unmapTree()
132 {
133  LBASSERT( isAttached() );
134  LBASSERT( !isMaster( ));
135 
136  getLocalNode()->unmapObject( this );
137 
138  if( _left )
139  _left->_unmapTree();
140  if( _right )
141  _right->_unmapTree();
142 }
143 
144 void VertexBufferDist::getInstanceData( co::DataOStream& os )
145 {
146  LBASSERT( _node );
147  os << _isRoot;
148 
149  if( _left && _right )
150  {
151  os << _left->getID() << _right->getID();
152 
153  if( _isRoot )
154  {
155  LBASSERT( _root );
156  const mesh::VertexBufferData& data = _root->_data;
157 
158  os << data.vertices << data.colors << data.normals << data.indices
159  << _root->_name;
160  }
161  }
162  else
163  {
164  os << co::UUID() << co::UUID();
165 
166  LBASSERT( dynamic_cast< const mesh::VertexBufferLeaf* >( _node ));
167  const mesh::VertexBufferLeaf* leaf =
168  static_cast< const mesh::VertexBufferLeaf* >( _node );
169 
170  os << leaf->_boundingBox[0] << leaf->_boundingBox[1]
171  << uint64_t( leaf->_vertexStart ) << uint64_t( leaf->_indexStart )
172  << uint64_t( leaf->_indexLength ) << leaf->_vertexLength;
173  }
174 
175  os << _node->_boundingSphere << _node->_range;
176 }
177 
178 void VertexBufferDist::applyInstanceData( co::DataIStream& is )
179 {
180  LBASSERT( !_node );
181 
182  mesh::VertexBufferNode* node = 0;
183  mesh::VertexBufferBase* base = 0;
184 
185  lunchbox::UUID leftID, rightID;
186  is >> _isRoot >> leftID >> rightID;
187 
188  if( leftID != 0 && rightID != 0 )
189  {
190  if( _isRoot )
191  {
193  mesh::VertexBufferData& data = root->_data;
194 
195  is >> data.vertices >> data.colors >> data.normals >> data.indices
196  >> root->_name;
197 
198  node = root;
199  _root = root;
200  }
201  else
202  {
203  LBASSERT( _root );
204  node = new mesh::VertexBufferNode;
205  }
206 
207  base = node;
208  _left = new VertexBufferDist( _root, 0 );
209  _right = new VertexBufferDist( _root, 0 );
210  co::LocalNodePtr to = getLocalNode();
211 #if CO_VERSION_GE( 1,1,0 )
212  co::NodePtr from = is.getRemoteNode();
213 #else
214  co::NodePtr from = is.getMaster();
215 #endif
216  const uint32_t sync1 = to->mapObjectNB( _left, leftID,
217  co::VERSION_OLDEST, from );
218  const uint32_t sync2 = to->mapObjectNB( _right, rightID,
219  co::VERSION_OLDEST, from );
220 
221  LBCHECK( to->mapObjectSync( sync1 ));
222  LBCHECK( to->mapObjectSync( sync2 ));
223 
224  node->_left = const_cast< mesh::VertexBufferBase* >( _left->_node );
225  node->_right = const_cast< mesh::VertexBufferBase* >( _right->_node );
226  }
227  else
228  {
229  LBASSERT( !_isRoot );
230  mesh::VertexBufferData& data =
231  const_cast< mesh::VertexBufferData& >( _root->_data );
233 
234  uint64_t i1, i2, i3;
235  is >> leaf->_boundingBox[0] >> leaf->_boundingBox[1]
236  >> i1 >> i2 >> i3 >> leaf->_vertexLength;
237  leaf->_vertexStart = size_t( i1 );
238  leaf->_indexStart = size_t( i2 );
239  leaf->_indexLength = size_t( i3 );
240 
241  base = leaf;
242  }
243 
244  LBASSERT( base );
245  is >> base->_boundingSphere >> base->_range;
246 
247  _node = base;
248 }
249 
250 }
Holds the final kd-tree data, sorted and reindexed.