Changeset 13041 for OpenSceneGraph/trunk/src/osgSim/Impostor.cpp
- Timestamp:
- 03/21/12 18:36:20 (14 months ago)
- Files:
-
- 1 modified
-
OpenSceneGraph/trunk/src/osgSim/Impostor.cpp (modified) (27 diffs)
Legend:
- Unmodified
- Added
- Removed
-
OpenSceneGraph/trunk/src/osgSim/Impostor.cpp
r11487 r13041 1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 2 2 * 3 * This library is open source and may be redistributed and/or modified under 4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 3 * This library is open source and may be redistributed and/or modified under 4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 5 5 * (at your option) any later version. The full license is in LICENSE file 6 6 * included with this distribution, and on the openscenegraph.org website. 7 * 7 * 8 8 * This library is distributed in the hope that it will be useful, 9 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 11 * OpenSceneGraph Public License for more details. 12 12 */ … … 20 20 // use this cull callback to allow the camera to traverse the Impostor's children without 21 21 // actuall having them assigned as children to the camea itself. This make the camera a 22 // decorator without ever directly being assigned to it. 22 // decorator without ever directly being assigned to it. 23 23 class ImpostorTraverseNodeCallback : public osg::NodeCallback 24 24 { 25 25 public: 26 26 27 ImpostorTraverseNodeCallback(osgSim::Impostor* node):_node(node) {} 27 ImpostorTraverseNodeCallback(osgSim::Impostor* node):_node(node) {} 28 28 29 29 virtual void operator()(osg::Node*, osg::NodeVisitor* nv) … … 31 31 _node->LOD::traverse(*nv); 32 32 } 33 33 34 34 osgSim::Impostor* _node; 35 35 }; … … 75 75 Impostor* previous_owner = is->getParent(); 76 76 ImpostorSpriteList& isl = previous_owner->_impostorSpriteListBuffer[contextID]; 77 77 78 78 // find and erase reference to is. 79 79 for(ImpostorSpriteList::iterator itr=isl.begin(); … … 89 89 } 90 90 is->setParent(this); 91 91 92 92 } 93 93 } … … 120 120 return; 121 121 } 122 122 123 123 124 124 osg::Vec3 eyeLocal = nv.getEyePoint(); 125 125 const BoundingSphere& bs = getBound(); 126 126 127 127 unsigned int contextID = cv->getState() ? cv->getState()->getContextID() : 0; 128 128 … … 138 138 } 139 139 else 140 { 140 { 141 141 142 142 // within the impostor distance threshold therefore attempt 143 143 // to use impostor instead. 144 144 145 145 RefMatrix& matrix = *cv->getModelViewMatrix(); 146 146 147 147 // search for the best fit ImpostorSprite; 148 148 ImpostorSprite* impostorSprite = findBestImpostorSprite(contextID,eyeLocal); 149 149 150 150 if (impostorSprite) 151 151 { … … 160 160 } 161 161 } 162 162 163 163 164 164 // need to think about sprite reuse and support for multiple context's. … … 171 171 // create the impostor sprite. 172 172 impostorSprite = createImpostorSprite(cv); 173 173 174 174 //if (impostorSprite) impostorSprite->_color.set(0.0f,0.0f,1.0f,1.0f); 175 175 176 176 } 177 177 //else impostorSprite->_color.set(1.0f,1.0f,1.0f,1.0f); 178 178 179 179 if (impostorSprite) 180 180 { 181 181 182 182 // update frame number to show that impostor is in action. 183 183 impostorSprite->setLastFrameUsed(cv->getTraversalNumber()); … … 186 186 187 187 StateSet* stateset = impostorSprite->getStateSet(); 188 188 189 189 if (stateset) cv->pushStateSet(stateset); 190 190 191 191 cv->addDrawableAndDepth(impostorSprite, &matrix, distance(getCenter(),matrix)); 192 192 193 193 if (stateset) cv->popStateSet(); 194 195 194 195 196 196 } 197 197 else 198 198 { 199 // no impostor has been selected or created so default to 199 // no impostor has been selected or created so default to 200 200 // traversing the usual LOD selected child. 201 201 LOD::traverse(nv); 202 202 } 203 203 204 204 } 205 205 } … … 215 215 cv->setUserData(impostorSpriteManager); 216 216 } 217 218 217 218 219 219 // default to true right now, will dertermine if perspective from the 220 220 // projection matrix... … … 237 237 float distance_local = lv_local.length(); 238 238 lv_local /= distance_local; 239 239 240 240 Vec3 sv_local = lv_local^camera_up_local; 241 241 sv_local.normalize(); 242 242 243 243 Vec3 up_local = sv_local^lv_local; 244 245 244 245 246 246 float width = bs.radius(); 247 247 if (isPerspectiveProjection) … … 250 250 width *= (distance_local/sqrtf(distance_local*distance_local-bs.radius2())); 251 251 } 252 252 253 253 // scale up and side vectors to sprite width. 254 254 up_local *= width; 255 255 sv_local *= width; 256 256 257 257 // create the corners of the sprite. 258 258 Vec3 c00(center_local - sv_local - up_local); … … 273 273 float s = c11_win.x()-c00_win.x(); 274 274 float t = c11_win.y()-c00_win.y(); 275 275 276 276 // may need to reverse sign of width or height if a matrix has 277 277 // been applied which flips the orientation of this subgraph. … … 282 282 // the texture dimensions to the nearest power of two. 283 283 // bias near 0.0 will almost always round down. 284 // bias near 1.0 will almost always round up. 284 // bias near 1.0 will almost always round up. 285 285 float bias = 0.7f; 286 286 … … 295 295 const osg::Viewport& viewport = *(cv->getViewport()); 296 296 297 // if dimension is bigger than window divide it down. 297 // if dimension is bigger than window divide it down. 298 298 while (new_s>viewport.width()) new_s /= 2; 299 299 300 // if dimension is bigger than window divide it down. 300 // if dimension is bigger than window divide it down. 301 301 while (new_t>viewport.height()) new_t /= 2; 302 302 303 303 // create the impostor sprite. 304 ImpostorSprite* impostorSprite = 304 ImpostorSprite* impostorSprite = 305 305 impostorSpriteManager->createOrReuseImpostorSprite(new_s,new_t,cv->getTraversalNumber()-cv->getNumberOfFrameToKeepImpostorSprites()); 306 306 … … 326 326 stateset->setRenderBinDetails(10,"DepthSortedBin"); 327 327 } 328 328 329 329 osg::Texture2D* texture = impostorSprite->getTexture(); 330 330 … … 339 339 Vec3* coords = impostorSprite->getCoords(); 340 340 Vec2* texcoords = impostorSprite->getTexCoords(); 341 341 342 342 coords[0] = c01; 343 343 texcoords[0].set(0.0f,1.0f); … … 351 351 coords[3] = c11; 352 352 texcoords[3].set(1.0f,1.0f); 353 353 354 354 impostorSprite->dirtyBound(); 355 355 356 356 Vec3* controlcoords = impostorSprite->getControlCoords(); 357 357 358 358 if (isPerspectiveProjection) 359 359 { … … 363 363 float one_minus_ratio = 1.0f-ratio; 364 364 Vec3 eye_local_ratio = eye_local*ratio; 365 365 366 366 controlcoords[0] = coords[0]*one_minus_ratio + eye_local_ratio; 367 367 controlcoords[1] = coords[1]*one_minus_ratio + eye_local_ratio; … … 387 387 Vec3 center_world = bs.center()*matrix; 388 388 389 389 390 390 osg::Camera* camera = impostorSprite->getCamera(); 391 391 if (!camera) … … 396 396 397 397 camera->setCullCallback(new ImpostorTraverseNodeCallback(this)); 398 398 399 399 osgUtil::RenderStage* previous_stage = cv->getRenderStage(); 400 400 401 401 // set up the background color and clear mask. 402 402 osg::Vec4 clear_color = previous_stage->getClearColor(); … … 404 404 camera->setClearColor(clear_color); 405 405 camera->setClearMask(previous_stage->getClearMask()); 406 407 406 407 408 408 // adjust camera left,right,up,down to fit (in world coords) 409 409 … … 412 412 Vec3 top_local ( center_local+up_local); 413 413 Vec3 right_local ( center_local+sv_local); 414 414 415 415 Vec3 near_world = near_local * matrix; 416 416 Vec3 far_world = far_local * matrix; 417 417 Vec3 top_world = top_local * matrix; 418 418 Vec3 right_world = right_local * matrix; 419 419 420 420 float znear = (near_world-eye_world).length(); 421 421 float zfar = (far_world-eye_world).length(); 422 422 423 423 float top = (top_world-center_world).length(); 424 424 float right = (right_world-center_world).length(); … … 445 445 Vec3 rotate_to = cv-> getLookVectorLocal(); 446 446 447 osg::Matrix rotate_matrix = 448 osg::Matrix::translate(-eye_local)* 447 osg::Matrix rotate_matrix = 448 osg::Matrix::translate(-eye_local)* 449 449 osg::Matrix::rotate(rotate_from,rotate_to)* 450 450 osg::Matrix::translate(eye_local)* … … 453 453 camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); 454 454 camera->setViewMatrix(rotate_matrix); 455 455 456 456 camera->setViewport(0,0,new_s,new_t); 457 457 … … 467 467 // do the cull traversal on the subgraph 468 468 camera->accept(*cv); 469 469 470 470 return impostorSprite; 471 471
