LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask) : LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB) { mBridge = this; mDrawable = root; root->setSpatialBridge(this); mBinIndex = -1; mRenderType = mDrawable->mRenderType; mDrawableType = mDrawable->mRenderType; mPartitionType = LLViewerRegion::PARTITION_VOLUME; mOctree->balance(); llassert(mDrawable); llassert(mDrawable->getRegion()); LLSpatialPartition *part = mDrawable->getRegion()->getSpatialPartition(mPartitionType); llassert(part); if (part) { part->put(this); } }
void LLDrawable::movePartition() { LLSpatialPartition* part = getSpatialPartition(); if (part) { part->move(this, getSpatialGroup()); } }
void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask, std::vector<LLSpatialGroup*>& groups) { #if !LL_RELEASE_FOR_DOWNLOAD LLGLState::checkClientArrays(mask); #endif LLSpatialBridge* last_bridge = NULL; LLSpatialPartition* last_part = NULL; glPushMatrix(); for (std::vector<LLSpatialGroup*>::iterator i = groups.begin(); i != groups.end(); ++i) { LLSpatialGroup* group = *i; if (group->mSpatialPartition->mRenderByGroup && !group->isDead()) { LLSpatialPartition* part = group->mSpatialPartition; if (part != last_part) { LLSpatialBridge* bridge = part->asBridge(); if (bridge != last_bridge) { glPopMatrix(); glPushMatrix(); if (bridge) { glMultMatrixf((F32*) bridge->mDrawable->getRenderMatrix().mMatrix); } last_bridge = bridge; } last_part = part; } LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA]; for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) { LLDrawInfo& params = **k; if (params.mParticle) { continue; } params.mVertexBuffer->setBuffer(mask); U32* indices_pointer = (U32*) params.mVertexBuffer->getIndicesPointer(); glDrawRangeElements(GL_TRIANGLES, params.mStart, params.mEnd, params.mCount, GL_UNSIGNED_INT, indices_pointer+params.mOffset); addIndicesDrawn(params.mCount); } } } glPopMatrix(); }
BOOL LLSpatialBridge::updateMove() { llassert_always(mDrawable); llassert_always(mDrawable->mVObjp); llassert_always(mDrawable->getRegion()); LLSpatialPartition* part = mDrawable->getRegion()->getSpatialPartition(mPartitionType); llassert_always(part); mOctree->balance(); if (part) { part->move(this, getSpatialGroup(), TRUE); } return TRUE; }
void LLDrawPoolAlpha::renderAlpha(U32 mask, std::vector<LLSpatialGroup*>& groups) { #if !LL_RELEASE_FOR_DOWNLOAD LLGLState::checkClientArrays(mask); #endif LLSpatialBridge* last_bridge = NULL; LLSpatialPartition* last_part = NULL; glPushMatrix(); LLGLDepthTest depth(GL_TRUE, GL_FALSE); for (std::vector<LLSpatialGroup*>::iterator i = groups.begin(); i != groups.end(); ++i) { LLSpatialGroup* group = *i; if (group->mSpatialPartition->mRenderByGroup && !group->isDead()) { LLSpatialPartition* part = group->mSpatialPartition; if (part != last_part) { LLSpatialBridge* bridge = part->asBridge(); if (bridge != last_bridge) { glPopMatrix(); glPushMatrix(); if (bridge) { glMultMatrixf((F32*) bridge->mDrawable->getRenderMatrix().mMatrix); } last_bridge = bridge; } // if (!last_part || part->mDepthMask != last_part->mDepthMask) // { // glDepthMask(part->mDepthMask); // } last_part = part; } renderGroupAlpha(group,LLRenderPass::PASS_ALPHA,mask,TRUE); } } glPopMatrix(); }
U32 LLViewerObjectList::renderObjectsForSelect(LLCamera &camera, BOOL pick_parcel_wall, BOOL keep_pick_list) { gRenderForSelect = TRUE; // LLTimer pick_timer; if (!keep_pick_list) { LLViewerObject *objectp; S32 i; // Reset all of the GL names to zero. for (i = 0; i < mObjects.count(); i++) { objectp = mObjects[i]; objectp->mGLName = 0; } mSelectPickList.clear(); std::vector<LLDrawable*> pick_drawables; for (i = 0; i < LLPipeline::NUM_PARTITIONS-1; i++) { LLSpatialPartition* part = gPipeline.getSpatialPartition(i); if (part) { part->cull(camera, &pick_drawables, TRUE); } } for (std::vector<LLDrawable*>::iterator iter = pick_drawables.begin(); iter != pick_drawables.end(); iter++) { LLDrawable* drawablep = *iter; if( !drawablep ) continue; LLViewerObject* last_objectp = NULL; for (S32 face_num = 0; face_num < drawablep->getNumFaces(); face_num++) { LLViewerObject* objectp = drawablep->getFace(face_num)->getViewerObject(); if (objectp && objectp != last_objectp) { mSelectPickList.insert(objectp); last_objectp = objectp; } } } LLHUDText::addPickable(mSelectPickList); for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); iter != LLCharacter::sInstances.end(); ++iter) { objectp = (LLVOAvatar*) *iter; if (!objectp->isDead()) { if (objectp->mDrawable.notNull() && objectp->mDrawable->isVisible()) { mSelectPickList.insert(objectp); } } } // add all hud objects to pick list LLVOAvatar* avatarp = gAgent.getAvatarObject(); if (avatarp) { LLViewerJointAttachment* attachmentp; for (attachmentp = avatarp->mAttachmentPoints.getFirstData(); attachmentp; attachmentp = avatarp->mAttachmentPoints.getNextData()) { if (attachmentp->getIsHUDAttachment()) { LLViewerObject* objectp = attachmentp->getObject(); if (objectp) { mSelectPickList.insert(objectp); for (U32 i = 0; i < objectp->mChildList.size(); i++) { LLViewerObject* childp = objectp->mChildList[i]; if (childp) { mSelectPickList.insert(childp); } } } } } } S32 num_pickables = (S32)mSelectPickList.size() + LLHUDIcon::getNumInstances(); if (num_pickables != 0) { S32 step = (0x000fffff - GL_NAME_INDEX_OFFSET) / num_pickables; std::set<LLViewerObject*>::iterator pick_it; i = 0; for (pick_it = mSelectPickList.begin(); pick_it != mSelectPickList.end();) { LLViewerObject* objp = (*pick_it); if (!objp || objp->isDead() || !objp->mbCanSelect) { mSelectPickList.erase(pick_it++); continue; } objp->mGLName = (i * step) + GL_NAME_INDEX_OFFSET; i++; ++pick_it; } LLHUDIcon::generatePickIDs(i * step, step); // At this point, we should only have live drawables/viewer objects gPipeline.renderForSelect(mSelectPickList); } } // // Render pass for selected objects // gViewerWindow->renderSelections( TRUE, pick_parcel_wall, FALSE ); // render pickable ui elements, like names, etc. LLHUDObject::renderAllForSelect(); gRenderForSelect = FALSE; //llinfos << "Rendered " << count << " for select" << llendl; //llinfos << "Took " << pick_timer.getElapsedTimeF32()*1000.f << "ms to pick" << llendl; return 0; }
void LLViewerObjectList::generatePickList(LLCamera &camera) { LLViewerObject *objectp; S32 i; // Reset all of the GL names to zero. for (i = 0; i < mObjects.count(); i++) { objectp = mObjects[i]; objectp->mGLName = 0; } mSelectPickList.clear(); std::vector<LLDrawable*> pick_drawables; for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) { LLSpatialPartition* part = region->getSpatialPartition(i); if (part) { part->cull(camera, &pick_drawables, TRUE); } } } for (std::vector<LLDrawable*>::iterator iter = pick_drawables.begin(); iter != pick_drawables.end(); iter++) { LLDrawable* drawablep = *iter; if( !drawablep ) continue; LLViewerObject* last_objectp = NULL; for (S32 face_num = 0; face_num < drawablep->getNumFaces(); face_num++) { LLViewerObject* objectp = drawablep->getFace(face_num)->getViewerObject(); if (objectp && objectp != last_objectp) { mSelectPickList.insert(objectp); last_objectp = objectp; } } } LLHUDText::addPickable(mSelectPickList); for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); iter != LLCharacter::sInstances.end(); ++iter) { objectp = (LLVOAvatar*) *iter; if (!objectp->isDead()) { if (objectp->mDrawable.notNull() && objectp->mDrawable->isVisible()) { mSelectPickList.insert(objectp); } } } // add all hud objects to pick list LLVOAvatar* avatarp = gAgent.getAvatarObject(); if (avatarp) { for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin(); iter != avatarp->mAttachmentPoints.end(); ) { LLVOAvatar::attachment_map_t::iterator curiter = iter++; LLViewerJointAttachment* attachmentp = curiter->second; if (attachmentp->getIsHUDAttachment()) { LLViewerObject* objectp = attachmentp->getObject(); if (objectp) { mSelectPickList.insert(objectp); LLViewerObject::const_child_list_t& child_list = objectp->getChildren(); for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); iter != child_list.end(); iter++) { LLViewerObject* childp = *iter; if (childp) { mSelectPickList.insert(childp); } } } } } } S32 num_pickables = (S32)mSelectPickList.size() + LLHUDIcon::getNumInstances(); if (num_pickables != 0) { S32 step = (0x000fffff - GL_NAME_INDEX_OFFSET) / num_pickables; std::set<LLViewerObject*>::iterator pick_it; i = 0; for (pick_it = mSelectPickList.begin(); pick_it != mSelectPickList.end();) { LLViewerObject* objp = (*pick_it); if (!objp || objp->isDead() || !objp->mbCanSelect) { mSelectPickList.erase(pick_it++); continue; } objp->mGLName = (i * step) + GL_NAME_INDEX_OFFSET; i++; ++pick_it; } LLHUDIcon::generatePickIDs(i * step, step); } }
// Paint the display! void display(BOOL rebuild, F32 zoom_factor, int subfield) { LLFastTimer t(LLFastTimer::FTM_RENDER); LLGLSDefault gls_default; LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE, GL_LEQUAL); // No clue where this is getting unset, but safe enough to reset it here. LLGLState::resetTextureStates(); #ifndef LL_RELEASE_FOR_DOWNLOAD LLGLState::checkStates(); LLGLState::checkTextureChannels(); #endif gPipeline.disableLights(); // Don't draw if the window is hidden or minimized. // In fact, must explicitly check the minimized state before drawing. // Attempting to draw into a minimized window causes a GL error. JC if ( !gViewerWindow->getActive() || !gViewerWindow->mWindow->getVisible() || gViewerWindow->mWindow->getMinimized() ) { // Clean up memory the pools may have allocated if (rebuild) { gFrameStats.start(LLFrameStats::REBUILD); gPipeline.rebuildPools(); } return; } gViewerWindow->checkSettings(); gViewerWindow->performPick(); #ifndef LL_RELEASE_FOR_DOWNLOAD LLGLState::checkStates(); LLGLState::checkTextureChannels(); #endif ////////////////////////////////////////////////////////// // // Logic for forcing window updates if we're in drone mode. // if (gNoRender) { #if LL_WINDOWS static F32 last_update_time = 0.f; if ((gFrameTimeSeconds - last_update_time) > 1.f) { InvalidateRect((HWND)gViewerWindow->getPlatformWindow(), NULL, FALSE); last_update_time = gFrameTimeSeconds; } #elif LL_DARWIN // MBW -- Do something clever here. #endif // Not actually rendering, don't bother. return; } // // Bail out if we're in the startup state and don't want to try to // render the world. // if (LLStartUp::getStartupState() < STATE_STARTED) { display_startup(); return; } //LLGLState::verify(FALSE); ///////////////////////////////////////////////// // // Update GL Texture statistics (used for discard logic?) // gFrameStats.start(LLFrameStats::UPDATE_TEX_STATS); stop_glerror(); LLImageGL::updateStats(gFrameTimeSeconds); LLVOAvatar::sRenderName = gSavedSettings.getS32("RenderName"); LLVOAvatar::sRenderGroupTitles = gSavedSettings.getBOOL("RenderGroupTitleAll"); gPipeline.mBackfaceCull = TRUE; gFrameCount++; if (gFocusMgr.getAppHasFocus()) { gForegroundFrameCount++; } ////////////////////////////////////////////////////////// // // Display start screen if we're teleporting, and skip render // if (gTeleportDisplay) { const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived. S32 attach_count = 0; if (gAgent.getAvatarObject()) { attach_count = gAgent.getAvatarObject()->getAttachmentCount(); } F32 teleport_save_time = TELEPORT_EXPIRY + TELEPORT_EXPIRY_PER_ATTACHMENT * attach_count; F32 teleport_elapsed = gTeleportDisplayTimer.getElapsedTimeF32(); F32 teleport_percent = teleport_elapsed * (100.f / teleport_save_time); if( (gAgent.getTeleportState() != LLAgent::TELEPORT_START) && (teleport_percent > 100.f) ) { // Give up. Don't keep the UI locked forever. gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); gAgent.setTeleportMessage(""); } const LLString& message = gAgent.getTeleportMessage(); switch( gAgent.getTeleportState() ) { case LLAgent::TELEPORT_START: // Transition to REQUESTED. Viewer has sent some kind // of TeleportRequest to the source simulator gTeleportDisplayTimer.reset(); gViewerWindow->setShowProgress(TRUE); gViewerWindow->setProgressPercent(0); gAgent.setTeleportState( LLAgent::TELEPORT_REQUESTED ); gAgent.setTeleportMessage( LLAgent::sTeleportProgressMessages["requesting"]); break; case LLAgent::TELEPORT_REQUESTED: // Waiting for source simulator to respond gViewerWindow->setProgressPercent( llmin(teleport_percent, 37.5f) ); gViewerWindow->setProgressString(message); break; case LLAgent::TELEPORT_MOVING: // Viewer has received destination location from source simulator gViewerWindow->setProgressPercent( llmin(teleport_percent, 75.f) ); gViewerWindow->setProgressString(message); break; case LLAgent::TELEPORT_START_ARRIVAL: // Transition to ARRIVING. Viewer has received avatar update, etc., from destination simulator gTeleportArrivalTimer.reset(); gViewerWindow->setProgressCancelButtonVisible(FALSE, "Cancel"); gViewerWindow->setProgressPercent(75.f); gAgent.setTeleportState( LLAgent::TELEPORT_ARRIVING ); gAgent.setTeleportMessage( LLAgent::sTeleportProgressMessages["arriving"]); gImageList.mForceResetTextureStats = TRUE; break; case LLAgent::TELEPORT_ARRIVING: // Make the user wait while content "pre-caches" { F32 arrival_fraction = (gTeleportArrivalTimer.getElapsedTimeF32() / TELEPORT_ARRIVAL_DELAY); if( arrival_fraction > 1.f ) { arrival_fraction = 1.f; gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); } gViewerWindow->setProgressCancelButtonVisible(FALSE, "Cancel"); gViewerWindow->setProgressPercent( arrival_fraction * 25.f + 75.f); gViewerWindow->setProgressString(message); } break; case LLAgent::TELEPORT_NONE: // No teleport in progress gViewerWindow->setShowProgress(FALSE); gTeleportDisplay = FALSE; break; } } else if(LLAppViewer::instance()->logoutRequestSent()) { F32 percent_done = gLogoutTimer.getElapsedTimeF32() * 100.f / gLogoutMaxTime; if (percent_done > 100.f) { percent_done = 100.f; } if( LLApp::isExiting() ) { percent_done = 100.f; } gViewerWindow->setProgressPercent( percent_done ); } else if (gRestoreGL) { F32 percent_done = gRestoreGLTimer.getElapsedTimeF32() * 100.f / RESTORE_GL_TIME; if( percent_done > 100.f ) { gViewerWindow->setShowProgress(FALSE); gRestoreGL = FALSE; } else { if( LLApp::isExiting() ) { percent_done = 100.f; } gViewerWindow->setProgressPercent( percent_done ); } } ////////////////////////// // // Prepare for the next frame // // Hmm... Should this be moved elsewhere? - djs 09/09/02 // do render-to-texture stuff here if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES)) { // LLFastTimer t(LLFastTimer::FTM_UPDATE_TEXTURES); if (LLDynamicTexture::updateAllInstances()) { glClear(GL_COLOR_BUFFER_BIT); } } ///////////////////////////// // // Update the camera // // gCamera->setZoomParameters(zoom_factor, subfield); gCamera->setNear(MIN_NEAR_PLANE); ////////////////////////// // // clear the next buffer // (must follow dynamic texture writing since that uses the frame buffer) // if (gDisconnected) { glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); render_disconnected_background(); } else if (!gViewerWindow->isPickPending()) { glClear( GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ); //DEBUG TEMPORARY glClear(GL_COLOR_BUFFER_BIT); } gViewerWindow->setupViewport(); ////////////////////////// // // Set rendering options // // stop_glerror(); if (gSavedSettings.getBOOL("ShowDepthBuffer")) { pre_show_depth_buffer(); } //MK if ((!RRenabled || !gAgent.mRRInterface.mContainsDetach) && gUseWireframe) //mk { glClearColor(0.5f, 0.5f, 0.5f, 0.f); glClear(GL_COLOR_BUFFER_BIT); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); LLPipeline::sUseOcclusion = FALSE; } else { LLPipeline::sUseOcclusion = gSavedSettings.getBOOL("UseOcclusion") && gGLManager.mHasOcclusionQuery && gFeatureManagerp->isFeatureAvailable("UseOcclusion"); } stop_glerror(); /////////////////////////////////////// // // Slam lighting parameters back to our defaults. // Note that these are not the same as GL defaults... stop_glerror(); F32 one[4] = {1.f, 1.f, 1.f, 1.f}; glLightModelfv (GL_LIGHT_MODEL_AMBIENT,one); stop_glerror(); //Increment drawable frame counter LLDrawable::incrementVisible(); ///////////////////////////////////// // // Render // // Actually push all of our triangles to the screen. // if (!gDisconnected) { if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) { //don't draw hud objects in this frame gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); } LLFastTimer t(LLFastTimer::FTM_WORLD_UPDATE); stop_glerror(); display_update_camera(); stop_glerror(); // *TODO: merge these two methods gHUDManager->updateEffects(); LLHUDObject::updateAll(); stop_glerror(); gFrameStats.start(LLFrameStats::UPDATE_GEOM); const F32 max_geom_update_time = 0.005f; // 5 ms update time gPipeline.updateGeom(max_geom_update_time); stop_glerror(); LLSpatialPartition* part = gPipeline.getSpatialPartition(LLPipeline::PARTITION_VOLUME); part->processImagery(gCamera); display_update_camera(); gFrameStats.start(LLFrameStats::UPDATE_CULL); gPipeline.updateCull(*gCamera); stop_glerror(); /////////////////////////////////// // // StateSort // // Responsible for taking visible objects, and adding them to the appropriate draw orders. // In the case of alpha objects, z-sorts them first. // Also creates special lists for outlines and selected face rendering. // { LLFastTimer t(LLFastTimer::FTM_REBUILD); gFrameStats.start(LLFrameStats::STATE_SORT); gPipeline.stateSort(*gCamera); stop_glerror(); if (rebuild) { ////////////////////////////////////// // // rebuildPools // // gFrameStats.start(LLFrameStats::REBUILD); gPipeline.rebuildPools(); stop_glerror(); } } } //// render frontmost floater opaque for occlusion culling purposes //LLFloater* frontmost_floaterp = gFloaterView->getFrontmost(); //// assumes frontmost floater with focus is opaque //if (frontmost_floaterp && gFocusMgr.childHasKeyboardFocus(frontmost_floaterp)) //{ // glMatrixMode(GL_MODELVIEW); // glPushMatrix(); // { // LLGLSNoTexture gls_no_texture; // glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); // glLoadIdentity(); // LLRect floater_rect = frontmost_floaterp->getScreenRect(); // // deflate by one pixel so rounding errors don't occlude outside of floater extents // floater_rect.stretch(-1); // LLRectf floater_3d_rect((F32)floater_rect.mLeft / (F32)gViewerWindow->getWindowWidth(), // (F32)floater_rect.mTop / (F32)gViewerWindow->getWindowHeight(), // (F32)floater_rect.mRight / (F32)gViewerWindow->getWindowWidth(), // (F32)floater_rect.mBottom / (F32)gViewerWindow->getWindowHeight()); // floater_3d_rect.translate(-0.5f, -0.5f); // glTranslatef(0.f, 0.f, -gCamera->getNear()); // glScalef(gCamera->getNear() * gCamera->getAspect() / sinf(gCamera->getView()), gCamera->getNear() / sinf(gCamera->getView()), 1.f); // glColor4fv(LLColor4::white.mV); // glBegin(GL_QUADS); // { // glVertex3f(floater_3d_rect.mLeft, floater_3d_rect.mBottom, 0.f); // glVertex3f(floater_3d_rect.mLeft, floater_3d_rect.mTop, 0.f); // glVertex3f(floater_3d_rect.mRight, floater_3d_rect.mTop, 0.f); // glVertex3f(floater_3d_rect.mRight, floater_3d_rect.mBottom, 0.f); // } // glEnd(); // glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // } // glPopMatrix(); //} if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot()) && !gRestoreGL && !gDisconnected) { gPipeline.renderGeom(*gCamera); stop_glerror(); } //render hud attachments glMatrixMode(GL_PROJECTION); glPushMatrix(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices(FALSE)) { LLCamera hud_cam = *gCamera; glClear(GL_DEPTH_BUFFER_BIT); LLVector3 origin = hud_cam.getOrigin(); hud_cam.setOrigin(-1.f,0,0); hud_cam.setAxes(LLVector3(1,0,0), LLVector3(0,1,0), LLVector3(0,0,1)); LLViewerCamera::updateFrustumPlanes(hud_cam, TRUE); //only render hud objects U32 mask = gPipeline.getRenderTypeMask(); gPipeline.setRenderTypeMask(0); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); BOOL has_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI); if (has_ui) { gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI); } BOOL use_occlusion = gSavedSettings.getBOOL("UseOcclusion"); gSavedSettings.setBOOL("UseOcclusion", FALSE); //cull, sort, and render hud objects gPipeline.updateCull(hud_cam); gPipeline.toggleRenderType(LLDrawPool::POOL_ALPHA_POST_WATER); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_BUMP); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_SIMPLE); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_VOLUME); { LLFastTimer ftm(LLFastTimer::FTM_REBUILD); gPipeline.stateSort(hud_cam); } gPipeline.renderGeom(hud_cam); //restore type mask gPipeline.setRenderTypeMask(mask); if (has_ui) { gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI); } gSavedSettings.setBOOL("UseOcclusion", use_occlusion); } glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); gFrameStats.start(LLFrameStats::RENDER_UI); if (gHandleKeysAsync) { process_keystrokes_async(); stop_glerror(); } #ifndef LL_RELEASE_FOR_DOWNLOAD LLGLState::checkStates(); #endif render_ui_and_swap(); #ifndef LL_RELEASE_FOR_DOWNLOAD LLGLState::checkStates(); #endif gFrameStats.start(LLFrameStats::MISC_END); stop_glerror(); }
// Returns true if you got at least one object void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask) { // [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c // Block rectangle selection if: // - prevented from editing and no exceptions are set (see below for the case where exceptions are set) // - prevented from interacting at all if ( (rlv_handler_t::isEnabled()) && ( ((gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) && (!gRlvHandler.hasException(RLV_BHVR_EDIT))) || (gRlvHandler.hasBehaviour(RLV_BHVR_INTERACT)) ) ) { return; } // [/RLVa:KB] LLVector3 av_pos = gAgent.getPositionAgent(); F32 select_dist_squared = gSavedSettings.getF32("MaxSelectDistance"); select_dist_squared = select_dist_squared * select_dist_squared; BOOL deselect = (mask == MASK_CONTROL); S32 left = llmin(x, mDragStartX); S32 right = llmax(x, mDragStartX); S32 top = llmax(y, mDragStartY); S32 bottom =llmin(y, mDragStartY); left = llround((F32) left * LLUI::getScaleFactor().mV[VX]); right = llround((F32) right * LLUI::getScaleFactor().mV[VX]); top = llround((F32) top * LLUI::getScaleFactor().mV[VY]); bottom = llround((F32) bottom * LLUI::getScaleFactor().mV[VY]); F32 old_far_plane = LLViewerCamera::getInstance()->getFar(); F32 old_near_plane = LLViewerCamera::getInstance()->getNear(); S32 width = right - left + 1; S32 height = top - bottom + 1; BOOL grow_selection = FALSE; BOOL shrink_selection = FALSE; if (height > mDragLastHeight || width > mDragLastWidth) { grow_selection = TRUE; } if (height < mDragLastHeight || width < mDragLastWidth) { shrink_selection = TRUE; } if (!grow_selection && !shrink_selection) { // nothing to do return; } mDragLastHeight = height; mDragLastWidth = width; S32 center_x = (left + right) / 2; S32 center_y = (top + bottom) / 2; // save drawing mode gGL.matrixMode(LLRender::MM_PROJECTION); gGL.pushMatrix(); BOOL limit_select_distance = gSavedSettings.getBOOL("LimitSelectDistance"); if (limit_select_distance) { // ...select distance from control LLVector3 relative_av_pos = av_pos; relative_av_pos -= LLViewerCamera::getInstance()->getOrigin(); F32 new_far = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() + gSavedSettings.getF32("MaxSelectDistance"); F32 new_near = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() - gSavedSettings.getF32("MaxSelectDistance"); new_near = llmax(new_near, 0.1f); LLViewerCamera::getInstance()->setFar(new_far); LLViewerCamera::getInstance()->setNear(new_near); } // [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.0e) | Modified: RLVa-1.0.0g if (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) { // We'll allow drag selection under fartouch, but only within the fartouch range // (just copy/paste the code above us to make that work, thank you Lindens!) LLVector3 relative_av_pos = av_pos; relative_av_pos -= LLViewerCamera::getInstance()->getOrigin(); F32 new_far = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() + 1.5f; F32 new_near = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() - 1.5f; new_near = llmax(new_near, 0.1f); LLViewerCamera::getInstance()->setFar(new_far); LLViewerCamera::getInstance()->setNear(new_near); // Usurp these two limit_select_distance = TRUE; select_dist_squared = 1.5f * 1.5f; } // [/RLVa:KB] LLViewerCamera::getInstance()->setPerspective(FOR_SELECTION, center_x-width/2, center_y-height/2, width, height, limit_select_distance); if (shrink_selection) { struct f : public LLSelectedObjectFunctor { virtual bool apply(LLViewerObject* vobjp) { LLDrawable* drawable = vobjp->mDrawable; if (!drawable || vobjp->getPCode() != LL_PCODE_VOLUME || vobjp->isAttachment()) { return true; } S32 result = LLViewerCamera::getInstance()->sphereInFrustum(drawable->getPositionAgent(), drawable->getRadius()); switch (result) { case 0: LLSelectMgr::getInstance()->unhighlightObjectOnly(vobjp); break; case 1: // check vertices if (!LLViewerCamera::getInstance()->areVertsVisible(vobjp, LLSelectMgr::sRectSelectInclusive)) { LLSelectMgr::getInstance()->unhighlightObjectOnly(vobjp); } break; default: break; } return true; } } func; LLSelectMgr::getInstance()->getHighlightedObjects()->applyToObjects(&func); } if (grow_selection) { std::vector<LLDrawable*> potentials; for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) { LLSpatialPartition* part = region->getSpatialPartition(i); if (part) { part->cull(*LLViewerCamera::getInstance(), &potentials, TRUE); } } } for (std::vector<LLDrawable*>::iterator iter = potentials.begin(); iter != potentials.end(); iter++) { LLDrawable* drawable = *iter; LLViewerObject* vobjp = drawable->getVObj(); if (!drawable || !vobjp || vobjp->getPCode() != LL_PCODE_VOLUME || vobjp->isAttachment() || (deselect && !vobjp->isSelected())) { continue; } if (limit_select_distance && dist_vec_squared(drawable->getWorldPosition(), av_pos) > select_dist_squared) { continue; } // [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Added: RLVa-1.3.0c if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canEdit(vobjp)) ) { continue; } // [/RLVa:KB] S32 result = LLViewerCamera::getInstance()->sphereInFrustum(drawable->getPositionAgent(), drawable->getRadius()); if (result) { switch (result) { case 1: // check vertices if (LLViewerCamera::getInstance()->areVertsVisible(vobjp, LLSelectMgr::sRectSelectInclusive)) { LLSelectMgr::getInstance()->highlightObjectOnly(vobjp); } break; case 2: LLSelectMgr::getInstance()->highlightObjectOnly(vobjp); break; default: break; } } } } // restore drawing mode gGL.matrixMode(LLRender::MM_PROJECTION); gGL.popMatrix(); gGL.matrixMode(LLRender::MM_MODELVIEW); // restore camera LLViewerCamera::getInstance()->setFar(old_far_plane); LLViewerCamera::getInstance()->setNear(old_near_plane); gViewerWindow->setup3DRender(); }
// Returns true if you got at least one object void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask) { LLVector3 av_pos = gAgent.getPositionAgent(); F32 select_dist_squared = gSavedSettings.getF32("MaxSelectDistance"); select_dist_squared = select_dist_squared * select_dist_squared; BOOL deselect = (mask == MASK_CONTROL); S32 left = llmin(x, mDragStartX); S32 right = llmax(x, mDragStartX); S32 top = llmax(y, mDragStartY); S32 bottom =llmin(y, mDragStartY); left = llround((F32) left * LLUI::sGLScaleFactor.mV[VX]); right = llround((F32) right * LLUI::sGLScaleFactor.mV[VX]); top = llround((F32) top * LLUI::sGLScaleFactor.mV[VY]); bottom = llround((F32) bottom * LLUI::sGLScaleFactor.mV[VY]); F32 old_far_plane = LLViewerCamera::getInstance()->getFar(); F32 old_near_plane = LLViewerCamera::getInstance()->getNear(); S32 width = right - left + 1; S32 height = top - bottom + 1; BOOL grow_selection = FALSE; BOOL shrink_selection = FALSE; if (height > mDragLastHeight || width > mDragLastWidth) { grow_selection = TRUE; } if (height < mDragLastHeight || width < mDragLastWidth) { shrink_selection = TRUE; } if (!grow_selection && !shrink_selection) { // nothing to do return; } mDragLastHeight = height; mDragLastWidth = width; S32 center_x = (left + right) / 2; S32 center_y = (top + bottom) / 2; // save drawing mode glMatrixMode(GL_PROJECTION); gGL.pushMatrix(); BOOL limit_select_distance = gSavedSettings.getBOOL("LimitSelectDistance"); if (limit_select_distance) { // ...select distance from control LLVector3 relative_av_pos = av_pos; relative_av_pos -= LLViewerCamera::getInstance()->getOrigin(); F32 new_far = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() + gSavedSettings.getF32("MaxSelectDistance"); F32 new_near = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() - gSavedSettings.getF32("MaxSelectDistance"); new_near = llmax(new_near, 0.1f); LLViewerCamera::getInstance()->setFar(new_far); LLViewerCamera::getInstance()->setNear(new_near); } LLViewerCamera::getInstance()->setPerspective(FOR_SELECTION, center_x-width/2, center_y-height/2, width, height, limit_select_distance); if (shrink_selection) { struct f : public LLSelectedObjectFunctor { virtual bool apply(LLViewerObject* vobjp) { LLDrawable* drawable = vobjp->mDrawable; if (!drawable || vobjp->getPCode() != LL_PCODE_VOLUME || vobjp->isAttachment()) { return true; } S32 result = LLViewerCamera::getInstance()->sphereInFrustum(drawable->getPositionAgent(), drawable->getRadius()); switch (result) { case 0: LLSelectMgr::getInstance()->unhighlightObjectOnly(vobjp); break; case 1: // check vertices if (!LLViewerCamera::getInstance()->areVertsVisible(vobjp, LLSelectMgr::sRectSelectInclusive)) { LLSelectMgr::getInstance()->unhighlightObjectOnly(vobjp); } break; default: break; } return true; } } func; LLSelectMgr::getInstance()->getHighlightedObjects()->applyToObjects(&func); } if (grow_selection) { std::vector<LLDrawable*> potentials; for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) { LLSpatialPartition* part = region->getSpatialPartition(i); if (part) { part->cull(*LLViewerCamera::getInstance(), &potentials, TRUE); } } } for (std::vector<LLDrawable*>::iterator iter = potentials.begin(); iter != potentials.end(); iter++) { LLDrawable* drawable = *iter; LLViewerObject* vobjp = drawable->getVObj(); if (!drawable || !vobjp || vobjp->getPCode() != LL_PCODE_VOLUME || vobjp->isAttachment() || (deselect && !vobjp->isSelected())) { continue; } if (limit_select_distance && dist_vec_squared(drawable->getWorldPosition(), av_pos) > select_dist_squared) { continue; } S32 result = LLViewerCamera::getInstance()->sphereInFrustum(drawable->getPositionAgent(), drawable->getRadius()); if (result) { switch (result) { case 1: // check vertices if (LLViewerCamera::getInstance()->areVertsVisible(vobjp, LLSelectMgr::sRectSelectInclusive)) { LLSelectMgr::getInstance()->highlightObjectOnly(vobjp); } break; case 2: LLSelectMgr::getInstance()->highlightObjectOnly(vobjp); break; default: break; } } } } // restore drawing mode glMatrixMode(GL_PROJECTION); gGL.popMatrix(); glMatrixMode(GL_MODELVIEW); // restore camera LLViewerCamera::getInstance()->setFar(old_far_plane); LLViewerCamera::getInstance()->setNear(old_near_plane); gViewerWindow->setup3DRender(); }