Sirikata
|
00001 /* Sirikata 00002 * SegmentedRegion.hpp 00003 * 00004 * Copyright (c) 2009, Tahir Azim 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions are 00009 * met: 00010 * * Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * * Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in 00014 * the documentation and/or other materials provided with the 00015 * distribution. 00016 * * Neither the name of Sirikata nor the names of its contributors may 00017 * be used to endorse or promote products derived from this software 00018 * without specific prior written permission. 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 00021 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 00022 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00023 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 00024 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00026 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00027 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00028 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00029 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 */ 00032 00033 #ifndef _SIRIKATA_SEGMENTED_REGION_HPP_ 00034 #define _SIRIKATA_SEGMENTED_REGION_HPP_ 00035 00036 00037 namespace Sirikata { 00038 00039 typedef struct SerializedBBox{ 00040 float32 minX; 00041 float32 minY; 00042 float32 minZ; 00043 00044 float32 maxX; 00045 float32 maxY; 00046 float32 maxZ; 00047 00048 void serialize(const BoundingBox3f& bbox) { 00049 minX = bbox.min().x; 00050 minY = bbox.min().y; 00051 minZ = bbox.min().z; 00052 00053 maxX = bbox.max().x; 00054 maxY = bbox.max().y; 00055 maxZ = bbox.max().z; 00056 } 00057 00058 void deserialize(BoundingBox3f& bbox) { 00059 bbox = BoundingBox3f(Vector3f(minX,minY,minZ), 00060 Vector3f(maxX, maxY, maxZ)); 00061 } 00062 00063 } SerializedBBox ; 00064 00065 typedef struct SegmentedRegion { 00066 00067 SegmentedRegion(SegmentedRegion* parent) { 00068 mLeafCount = 0; 00069 mLeftChild = mRightChild = NULL; 00070 mParent = parent; 00071 mServer = 0; 00072 mLoadValue = 0; 00073 mSplitAxis = UNDEFINED; 00074 } 00075 00076 void destroy() { 00077 if (mLeftChild != NULL) { 00078 mLeftChild->destroy(); 00079 00080 SegmentedRegion* prevLeftChild = mLeftChild; 00081 mLeftChild = NULL; 00082 00083 delete prevLeftChild; 00084 } 00085 if (mRightChild != NULL) { 00086 mRightChild->destroy(); 00087 00088 SegmentedRegion* prevRightChild = mRightChild; 00089 mRightChild = NULL; 00090 00091 delete prevRightChild; 00092 } 00093 } 00094 00095 SegmentedRegion* getRandomLeaf() { 00096 if (mRightChild == NULL && mLeftChild == NULL) { 00097 return this; 00098 } 00099 00100 int random = rand() % 2; 00101 if (random == 0) 00102 return mLeftChild->getRandomLeaf(); 00103 else 00104 return mRightChild->getRandomLeaf(); 00105 } 00106 00107 SegmentedRegion* getSibling(SegmentedRegion* region) { 00108 assert(region->mLeftChild == NULL && region->mRightChild == NULL); 00109 00110 if (mRightChild == NULL && mLeftChild == NULL) return NULL; 00111 00112 if (mRightChild == region) return mLeftChild; 00113 if (mLeftChild == region) return mRightChild; 00114 00115 SegmentedRegion* r1 = mLeftChild->getSibling(region); 00116 00117 if (r1 != NULL) return r1; 00118 00119 SegmentedRegion* r2 = mRightChild->getSibling(region); 00120 00121 if (r2 != NULL) return r2; 00122 00123 return NULL; 00124 } 00125 00126 SegmentedRegion* getParent(SegmentedRegion* region) { 00127 if (mRightChild == NULL && mLeftChild == NULL) return NULL; 00128 00129 if (mRightChild == region) return this; 00130 if (mLeftChild == region) return this; 00131 00132 SegmentedRegion* r1 = mLeftChild->getParent(region); 00133 00134 if (r1 != NULL) return r1; 00135 00136 SegmentedRegion* r2 = mRightChild->getParent(region); 00137 00138 if (r2 != NULL) return r2; 00139 00140 return NULL; 00141 } 00142 00143 int countServers() const { 00144 if (mRightChild == NULL && mLeftChild == NULL) return 1; 00145 00146 int count = 0; 00147 00148 if (mLeftChild != NULL) { 00149 count += mLeftChild->countServers(); 00150 } 00151 if (mRightChild != NULL) { 00152 count += mRightChild->countServers(); 00153 } 00154 00155 return count; 00156 } 00157 00158 int countNodes() const { 00159 if (mRightChild == NULL && mLeftChild == NULL) return 1; 00160 00161 int count = 0; 00162 00163 if (mLeftChild != NULL) { 00164 count += mLeftChild->countNodes(); 00165 } 00166 if (mRightChild != NULL) { 00167 count += mRightChild->countNodes(); 00168 } 00169 00170 return count+1; 00171 } 00172 00173 SegmentedRegion* lookupSegmentedRegion(const ServerID& server_id) { 00174 if (mRightChild == NULL && mLeftChild == NULL && mServer==server_id) { 00175 return this; 00176 } 00177 00178 SegmentedRegion* segRegion = mLeftChild->lookupSegmentedRegion(server_id); 00179 00180 if (segRegion != NULL) { 00181 return segRegion; 00182 } 00183 00184 segRegion = mRightChild->lookupSegmentedRegion(server_id); 00185 00186 if (segRegion != NULL) { 00187 return segRegion; 00188 } 00189 00190 return NULL; 00191 } 00192 00193 SegmentedRegion* lookup(const Vector3f& pos) const { 00194 if (mRightChild == NULL && mLeftChild == NULL) { 00195 if (mBoundingBox.contains(pos) || mBoundingBox.degenerate()) { 00196 return ((SegmentedRegion*)this); 00197 } 00198 } 00199 00200 SegmentedRegion* region = NULL; 00201 00202 if (mLeftChild != NULL && mLeftChild->mBoundingBox.contains(pos)) { 00203 region = mLeftChild->lookup(pos); 00204 } 00205 00206 if (region == NULL && mRightChild!=NULL && mRightChild->mBoundingBox.contains(pos)){ 00207 region= mRightChild->lookup(pos); 00208 } 00209 00210 return region; 00211 } 00212 00213 void lookupBoundingBox(const BoundingBox3f& bbox, std::vector<SegmentedRegion*>& intersectingLeaves) { 00214 if (mRightChild == NULL && mLeftChild == NULL) { 00215 if (mBoundingBox.intersects(bbox)) { 00216 intersectingLeaves.push_back((SegmentedRegion*) this); 00217 } 00218 } 00219 00220 if (mLeftChild != NULL && mLeftChild->mBoundingBox.intersects(bbox)) { 00221 mLeftChild->lookupBoundingBox(bbox, intersectingLeaves); 00222 } 00223 00224 if ( mRightChild!=NULL && mRightChild->mBoundingBox.intersects(bbox)) { 00225 mRightChild->lookupBoundingBox(bbox, intersectingLeaves); 00226 } 00227 } 00228 00229 void serverRegion(const ServerID& server, BoundingBoxList& boundingBoxList) const { 00230 if (mServer == server && mRightChild==NULL && mLeftChild==NULL) { 00231 boundingBoxList.push_back(mBoundingBox); 00232 return; 00233 } 00234 00235 if (mLeftChild != NULL) { 00236 mLeftChild->serverRegion(server, boundingBoxList); 00237 } 00238 00239 if (mRightChild != NULL) { 00240 mRightChild->serverRegion(server, boundingBoxList); 00241 } 00242 00243 return; 00244 } 00245 00246 ServerID mServer; 00247 SegmentedRegion* mLeftChild; 00248 SegmentedRegion* mRightChild; 00249 SegmentedRegion* mParent; 00250 00251 enum SplitAxis{ X, Y, Z, UNDEFINED }; 00252 00253 SplitAxis mSplitAxis; 00254 00255 uint32 mLeafCount; 00256 BoundingBox3f mBoundingBox; 00257 uint32 mLoadValue; 00258 00259 } SegmentedRegion; 00260 00261 typedef struct SerializedSegmentedRegion { 00262 ServerID mServerID; 00263 uint32 mLeftChildIdx; 00264 uint32 mRightChildIdx; 00265 SerializedBBox mBoundingBox; 00266 uint32 mLeafCount; 00267 00268 SerializedSegmentedRegion() { 00269 mLeftChildIdx = 0; 00270 mRightChildIdx = 0; 00271 } 00272 00273 } SerializedSegmentedRegion; 00274 00275 00276 00277 typedef struct SerializedBSPTree { 00278 uint32 mNodeCount; 00279 SerializedSegmentedRegion* mSegmentedRegions; //allocate dynamically based on 00280 //size of region. 00281 00282 SerializedBSPTree(int numNodes) { 00283 mNodeCount = numNodes; 00284 mSegmentedRegions = new SerializedSegmentedRegion[numNodes]; 00285 } 00286 00287 ~SerializedBSPTree() { 00288 delete mSegmentedRegions; 00289 } 00290 00291 void deserializeBSPTree(SegmentedRegion* region, uint32 idx, 00292 SerializedBSPTree* serializedTree) 00293 { 00294 assert(idx<serializedTree->mNodeCount); 00295 00296 region->mServer = serializedTree->mSegmentedRegions[idx].mServerID; 00297 00298 region->mLeafCount = serializedTree->mSegmentedRegions[idx].mLeafCount; 00299 00300 serializedTree->mSegmentedRegions[idx].mBoundingBox.deserialize(region->mBoundingBox); 00301 00302 if (serializedTree->mSegmentedRegions[idx].mLeftChildIdx == 0 && 00303 serializedTree->mSegmentedRegions[idx].mRightChildIdx == 0) 00304 { 00305 //std::cout << region->mServer << " : " <<region->mLeafCount << "\n"; 00306 //std::cout << region->mBoundingBox << "\n"; 00307 } 00308 00309 //std::cout << "left " << serializedTree->mSegmentedRegions[idx].mLeftChildIdx << "\n"; 00310 //std::cout << "right " << serializedTree->mSegmentedRegions[idx].mRightChildIdx << "\n"; 00311 00312 if (serializedTree->mSegmentedRegions[idx].mLeftChildIdx != 0) { 00313 region->mLeftChild = new SegmentedRegion(region); 00314 deserializeBSPTree(region->mLeftChild, serializedTree->mSegmentedRegions[idx].mLeftChildIdx, serializedTree); 00315 } 00316 00317 if (serializedTree->mSegmentedRegions[idx].mRightChildIdx != 0) { 00318 region->mRightChild = new SegmentedRegion(region); 00319 deserializeBSPTree(region->mRightChild,serializedTree->mSegmentedRegions[idx].mRightChildIdx, serializedTree); 00320 } 00321 } 00322 00323 private: 00324 SerializedBSPTree() { 00325 mNodeCount = 0; 00326 } 00327 00328 } SerializedBSPTree; 00329 00330 00331 } 00332 #endif