//----------------------------------------------------------------------------- // zoom() //----------------------------------------------------------------------------- void LLImagePreviewAvatar::zoom(F32 zoom_amt) { mCameraZoom = llclamp(mCameraZoom + zoom_amt, 1.f, 10.f); }
void LLImageTGA::decodeColorMapPixel15( U8* dst, const U8* src ) { S32 index = llclamp( *src - mColorMapStart, 0, mColorMapLength - 1 ); decodeTruecolorPixel15( dst, mColorMap + 2 * index ); }
//----------------------------------------------------------------------------- // LLEyeMotion::onUpdate() //----------------------------------------------------------------------------- BOOL LLEyeMotion::onUpdate(F32 time, U8* joint_mask) { // Compute eye rotation. LLQuaternion target_eye_rot; LLVector3 eye_look_at; F32 vergence; //calculate jitter if (mEyeJitterTimer.getElapsedTimeF32() > mEyeJitterTime) { mEyeJitterTime = EYE_JITTER_MIN_TIME + ll_frand(EYE_JITTER_MAX_TIME - EYE_JITTER_MIN_TIME); mEyeJitterYaw = (ll_frand(2.f) - 1.f) * EYE_JITTER_MAX_YAW; mEyeJitterPitch = (ll_frand(2.f) - 1.f) * EYE_JITTER_MAX_PITCH; // make sure lookaway time count gets updated, because we're resetting the timer mEyeLookAwayTime -= llmax(0.f, mEyeJitterTimer.getElapsedTimeF32()); mEyeJitterTimer.reset(); } else if (mEyeJitterTimer.getElapsedTimeF32() > mEyeLookAwayTime) { if (ll_frand() > 0.1f) { // blink while moving eyes some percentage of the time mEyeBlinkTime = mEyeBlinkTimer.getElapsedTimeF32(); } if (mEyeLookAwayYaw == 0.f && mEyeLookAwayPitch == 0.f) { mEyeLookAwayYaw = (ll_frand(2.f) - 1.f) * EYE_LOOK_AWAY_MAX_YAW; mEyeLookAwayPitch = (ll_frand(2.f) - 1.f) * EYE_LOOK_AWAY_MAX_PITCH; mEyeLookAwayTime = EYE_LOOK_BACK_MIN_TIME + ll_frand(EYE_LOOK_BACK_MAX_TIME - EYE_LOOK_BACK_MIN_TIME); } else { mEyeLookAwayYaw = 0.f; mEyeLookAwayPitch = 0.f; mEyeLookAwayTime = EYE_LOOK_AWAY_MIN_TIME + ll_frand(EYE_LOOK_AWAY_MAX_TIME - EYE_LOOK_AWAY_MIN_TIME); } } // do blinking if (!mEyesClosed && mEyeBlinkTimer.getElapsedTimeF32() >= mEyeBlinkTime) { F32 leftEyeBlinkMorph = mEyeBlinkTimer.getElapsedTimeF32() - mEyeBlinkTime; F32 rightEyeBlinkMorph = leftEyeBlinkMorph - EYE_BLINK_TIME_DELTA; leftEyeBlinkMorph = llclamp(leftEyeBlinkMorph / EYE_BLINK_SPEED, 0.f, 1.f); rightEyeBlinkMorph = llclamp(rightEyeBlinkMorph / EYE_BLINK_SPEED, 0.f, 1.f); mCharacter->setVisualParamWeight("Blink_Left", leftEyeBlinkMorph); mCharacter->setVisualParamWeight("Blink_Right", rightEyeBlinkMorph); mCharacter->updateVisualParams(); if (rightEyeBlinkMorph == 1.f) { mEyesClosed = TRUE; mEyeBlinkTime = EYE_BLINK_CLOSE_TIME; mEyeBlinkTimer.reset(); } } else if (mEyesClosed) { if (mEyeBlinkTimer.getElapsedTimeF32() >= mEyeBlinkTime) { F32 leftEyeBlinkMorph = mEyeBlinkTimer.getElapsedTimeF32() - mEyeBlinkTime; F32 rightEyeBlinkMorph = leftEyeBlinkMorph - EYE_BLINK_TIME_DELTA; leftEyeBlinkMorph = 1.f - llclamp(leftEyeBlinkMorph / EYE_BLINK_SPEED, 0.f, 1.f); rightEyeBlinkMorph = 1.f - llclamp(rightEyeBlinkMorph / EYE_BLINK_SPEED, 0.f, 1.f); mCharacter->setVisualParamWeight("Blink_Left", leftEyeBlinkMorph); mCharacter->setVisualParamWeight("Blink_Right", rightEyeBlinkMorph); mCharacter->updateVisualParams(); if (rightEyeBlinkMorph == 0.f) { mEyesClosed = FALSE; mEyeBlinkTime = EYE_BLINK_MIN_TIME + ll_frand(EYE_BLINK_MAX_TIME - EYE_BLINK_MIN_TIME); mEyeBlinkTimer.reset(); } } } BOOL has_eye_target = FALSE; LLVector3* targetPos = (LLVector3*)mCharacter->getAnimationData("LookAtPoint"); if (targetPos) { LLVector3 skyward(0.f, 0.f, 1.f); LLVector3 left; LLVector3 up; eye_look_at = *targetPos; has_eye_target = TRUE; F32 lookAtDistance = eye_look_at.normVec(); left.setVec(skyward % eye_look_at); up.setVec(eye_look_at % left); target_eye_rot = LLQuaternion(eye_look_at, left, up); // convert target rotation to head-local coordinates target_eye_rot *= ~mHeadJoint->getWorldRotation(); // eliminate any Euler roll - we're lucky that roll is applied last. F32 roll, pitch, yaw; target_eye_rot.getEulerAngles(&roll, &pitch, &yaw); target_eye_rot.setQuat(0.0f, pitch, yaw); // constrain target orientation to be in front of avatar's face target_eye_rot.constrain(EYE_ROT_LIMIT_ANGLE); // calculate vergence F32 interocular_dist = (mLeftEyeState->getJoint()->getWorldPosition() - mRightEyeState->getJoint()->getWorldPosition()).magVec(); vergence = -atan2((interocular_dist / 2.f), lookAtDistance); llclamp(vergence, -F_PI_BY_TWO, 0.f); } else { target_eye_rot = LLQuaternion::DEFAULT; vergence = 0.f; } //RN: subtract 4 degrees to account for foveal angular offset relative to pupil vergence += 4.f * DEG_TO_RAD; // calculate eye jitter LLQuaternion eye_jitter_rot; // vergence not too high... if (vergence > -0.05f) { //...go ahead and jitter eye_jitter_rot.setQuat(0.f, mEyeJitterPitch + mEyeLookAwayPitch, mEyeJitterYaw + mEyeLookAwayYaw); } else { //...or don't eye_jitter_rot.loadIdentity(); } // calculate vergence of eyes as an object gets closer to the avatar's head LLQuaternion vergence_quat; if (has_eye_target) { vergence_quat.setQuat(vergence, LLVector3(0.f, 0.f, 1.f)); } else { vergence_quat.loadIdentity(); } // calculate eye rotations LLQuaternion left_eye_rot = target_eye_rot; left_eye_rot = vergence_quat * eye_jitter_rot * left_eye_rot; LLQuaternion right_eye_rot = target_eye_rot; vergence_quat.transQuat(); right_eye_rot = vergence_quat * eye_jitter_rot * right_eye_rot; mLeftEyeState->setRotation( left_eye_rot ); mRightEyeState->setRotation( right_eye_rot ); return TRUE; }
//----------------------------------------------------------------------------- // rotate() //----------------------------------------------------------------------------- void LLPreviewSculpted::rotate(F32 yaw_radians, F32 pitch_radians) { mCameraYaw = mCameraYaw + yaw_radians; mCameraPitch = llclamp(mCameraPitch + pitch_radians, -0.95f * F_PI_BY_TWO, 0.95f * F_PI_BY_TWO); }
void LLPreviewSculpted::pan(F32 right, F32 up) { mCameraOffset.mV[VY] = llclamp(mCameraOffset.mV[VY] + right * mCameraDistance / mCameraZoom, -1.f, 1.f); mCameraOffset.mV[VZ] = llclamp(mCameraOffset.mV[VZ] + up * mCameraDistance / mCameraZoom, -1.f, 1.f); }
void render_hud_attachments() { glMatrixMode(GL_PROJECTION); glPushMatrix(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glh::matrix4f current_proj = glh_get_current_projection(); glh::matrix4f current_mod = glh_get_current_modelview(); // clamp target zoom level to reasonable values gAgent.mHUDTargetZoom = llclamp(gAgent.mHUDTargetZoom, 0.1f, 1.f); // smoothly interpolate current zoom level gAgent.mHUDCurZoom = lerp(gAgent.mHUDCurZoom, gAgent.mHUDTargetZoom, LLCriticalDamp::getInterpolant(0.03f)); if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices()) { LLCamera hud_cam = *LLViewerCamera::getInstance(); 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); bool render_particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES) && gSavedSettings.getBOOL("RenderHUDParticles"); //only render hud objects U32 mask = gPipeline.getRenderTypeMask(); // turn off everything gPipeline.setRenderTypeMask(0); // turn on HUD gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); // turn on HUD particles gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES); // if particles are off, turn off hud-particles as well if (!render_particles) { // turn back off HUD particles gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES); } bool has_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI); if (has_ui) { gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI); } S32 use_occlusion = LLPipeline::sUseOcclusion; LLPipeline::sUseOcclusion = 0; LLPipeline::sDisableShaders = TRUE; //cull, sort, and render hud objects static LLCullResult result; LLSpatialGroup::sNoDelete = TRUE; gPipeline.updateCull(hud_cam, result); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_BUMP); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_SIMPLE); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_VOLUME); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT); gPipeline.stateSort(hud_cam, result); gPipeline.renderGeom(hud_cam); LLSpatialGroup::sNoDelete = FALSE; render_hud_elements(); //restore type mask gPipeline.setRenderTypeMask(mask); if (has_ui) { gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI); } LLPipeline::sUseOcclusion = use_occlusion; LLPipeline::sDisableShaders = FALSE; } glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glh_set_current_projection(current_proj); glh_set_current_modelview(current_mod); }
// Takes a line defined by "point_a" and "point_b" and determines the closest (to point_a) // point where the the line intersects an object or the land surface. Stores the results // in "intersection" and "intersection_normal" and returns a scalar value that represents // the normalized distance along the line from "point_a" to "intersection". // // Currently assumes point_a and point_b only differ in z-direction, // but it may eventually become more general. F32 LLWorld::resolveStepHeightGlobal(const LLVOAvatar* avatarp, const LLVector3d &point_a, const LLVector3d &point_b, LLVector3d &intersection, LLVector3 &intersection_normal, LLViewerObject **viewerObjectPtr) { // initialize return value to null if (viewerObjectPtr) { *viewerObjectPtr = NULL; } LLViewerRegion *regionp = getRegionFromPosGlobal(point_a); if (!regionp) { // We're outside the world intersection = 0.5f * (point_a + point_b); intersection_normal.setVec(0.0f, 0.0f, 1.0f); return 0.5f; } // calculate the length of the segment F32 segment_length = (F32)((point_a - point_b).length()); if (0.0f == segment_length) { intersection = point_a; intersection_normal.setVec(0.0f, 0.0f, 1.0f); return segment_length; } // get land height // Note: we assume that the line is parallel to z-axis here LLVector3d land_intersection = point_a; F32 normalized_land_distance; land_intersection.mdV[VZ] = regionp->getLand().resolveHeightGlobal(point_a); normalized_land_distance = (F32)(point_a.mdV[VZ] - land_intersection.mdV[VZ]) / segment_length; intersection = land_intersection; intersection_normal = resolveLandNormalGlobal(land_intersection); if (avatarp && !avatarp->mFootPlane.isExactlyClear()) { LLVector3 foot_plane_normal(avatarp->mFootPlane.mV); LLVector3 start_pt = avatarp->getRegion()->getPosRegionFromGlobal(point_a); // added 0.05 meters to compensate for error in foot plane reported by Havok F32 norm_dist_from_plane = ((start_pt * foot_plane_normal) - avatarp->mFootPlane.mV[VW]) + 0.05f; norm_dist_from_plane = llclamp(norm_dist_from_plane / segment_length, 0.f, 1.f); if (norm_dist_from_plane < normalized_land_distance) { // collided with object before land normalized_land_distance = norm_dist_from_plane; intersection = point_a; intersection.mdV[VZ] -= norm_dist_from_plane * segment_length; intersection_normal = foot_plane_normal; } else { intersection = land_intersection; intersection_normal = resolveLandNormalGlobal(land_intersection); } } return normalized_land_distance; }
BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask) { BOOL handled = FALSE; // We only handle the click if the click both started and ended within us if( hasMouseCapture() ) { // Make sure the mouse in still over the application. We don't want to make the parent // so big that we can't see the resize handle any more. S32 screen_x; S32 screen_y; localPointToScreen(x, y, &screen_x, &screen_y); const LLRect valid_rect = getRootView()->getRect(); screen_x = llclamp( screen_x, valid_rect.mLeft, valid_rect.mRight ); screen_y = llclamp( screen_y, valid_rect.mBottom, valid_rect.mTop ); LLView* resizing_view = getParent(); if( resizing_view ) { // Resize the parent LLRect orig_rect = resizing_view->getRect(); LLRect scaled_rect = orig_rect; S32 delta_x = screen_x - mDragLastScreenX; S32 delta_y = screen_y - mDragLastScreenY; LLCoordGL mouse_dir; // use hysteresis on mouse motion to preserve user intent when mouse stops moving mouse_dir.mX = (screen_x == mLastMouseScreenX) ? mLastMouseDir.mX : screen_x - mLastMouseScreenX; mouse_dir.mY = (screen_y == mLastMouseScreenY) ? mLastMouseDir.mY : screen_y - mLastMouseScreenY; mLastMouseScreenX = screen_x; mLastMouseScreenY = screen_y; mLastMouseDir = mouse_dir; S32 x_multiple = 1; S32 y_multiple = 1; switch( mCorner ) { case LEFT_TOP: x_multiple = -1; y_multiple = 1; break; case LEFT_BOTTOM: x_multiple = -1; y_multiple = -1; break; case RIGHT_TOP: x_multiple = 1; y_multiple = 1; break; case RIGHT_BOTTOM: x_multiple = 1; y_multiple = -1; break; } S32 new_width = orig_rect.getWidth() + x_multiple * delta_x; if( new_width < mMinWidth ) { new_width = mMinWidth; delta_x = x_multiple * (mMinWidth - orig_rect.getWidth()); } S32 new_height = orig_rect.getHeight() + y_multiple * delta_y; if( new_height < mMinHeight ) { new_height = mMinHeight; delta_y = y_multiple * (mMinHeight - orig_rect.getHeight()); } switch( mCorner ) { case LEFT_TOP: scaled_rect.translate(delta_x, 0); break; case LEFT_BOTTOM: scaled_rect.translate(delta_x, delta_y); break; case RIGHT_TOP: break; case RIGHT_BOTTOM: scaled_rect.translate(0, delta_y); break; } // temporarily set new parent rect scaled_rect.mRight = scaled_rect.mLeft + new_width; scaled_rect.mTop = scaled_rect.mBottom + new_height; resizing_view->setRect(scaled_rect); LLView* snap_view = NULL; LLView* test_view = NULL; // now do snapping switch(mCorner) { case LEFT_TOP: snap_view = resizing_view->findSnapEdge(scaled_rect.mLeft, mouse_dir, SNAP_LEFT, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin")); test_view = resizing_view->findSnapEdge(scaled_rect.mTop, mouse_dir, SNAP_TOP, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin")); if (!snap_view) { snap_view = test_view; } break; case LEFT_BOTTOM: snap_view = resizing_view->findSnapEdge(scaled_rect.mLeft, mouse_dir, SNAP_LEFT, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin")); test_view = resizing_view->findSnapEdge(scaled_rect.mBottom, mouse_dir, SNAP_BOTTOM, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin")); if (!snap_view) { snap_view = test_view; } break; case RIGHT_TOP: snap_view = resizing_view->findSnapEdge(scaled_rect.mRight, mouse_dir, SNAP_RIGHT, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin")); test_view = resizing_view->findSnapEdge(scaled_rect.mTop, mouse_dir, SNAP_TOP, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin")); if (!snap_view) { snap_view = test_view; } break; case RIGHT_BOTTOM: snap_view = resizing_view->findSnapEdge(scaled_rect.mRight, mouse_dir, SNAP_RIGHT, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin")); test_view = resizing_view->findSnapEdge(scaled_rect.mBottom, mouse_dir, SNAP_BOTTOM, SNAP_PARENT_AND_SIBLINGS, LLUI::sConfigGroup->getS32("SnapMargin")); if (!snap_view) { snap_view = test_view; } break; } // register "snap" behavior with snapped view resizing_view->snappedTo(snap_view); // reset parent rect resizing_view->setRect(orig_rect); // translate and scale to new shape resizing_view->userSetShape(scaled_rect); // update last valid mouse cursor position based on resized view's actual size LLRect new_rect = resizing_view->getRect(); switch(mCorner) { case LEFT_TOP: mDragLastScreenX += new_rect.mLeft - orig_rect.mLeft; mDragLastScreenY += new_rect.mTop - orig_rect.mTop; break; case LEFT_BOTTOM: mDragLastScreenX += new_rect.mLeft - orig_rect.mLeft; mDragLastScreenY += new_rect.mBottom- orig_rect.mBottom; break; case RIGHT_TOP: mDragLastScreenX += new_rect.mRight - orig_rect.mRight; mDragLastScreenY += new_rect.mTop - orig_rect.mTop; break; case RIGHT_BOTTOM: mDragLastScreenX += new_rect.mRight - orig_rect.mRight; mDragLastScreenY += new_rect.mBottom- orig_rect.mBottom; break; default: break; } } handled = TRUE; } else // don't have mouse capture { if( pointInHandle( x, y ) ) { handled = TRUE; } } if( handled ) { switch( mCorner ) { case RIGHT_BOTTOM: case LEFT_TOP: getWindow()->setCursor(UI_CURSOR_SIZENWSE); break; case LEFT_BOTTOM: case RIGHT_TOP: getWindow()->setCursor(UI_CURSOR_SIZENESW); break; } } return handled; } // end handleHover
void LLViewerPartGroup::updateParticles(const F32 lastdt) { LLMemType mt(LLMemType::MTYPE_PARTICLES); F32 dt; LLVector3 gravity(0.f, 0.f, GRAVITY); LLViewerRegion *regionp = getRegion(); S32 end = (S32) mParticles.size(); for (S32 i = 0 ; i < (S32)mParticles.size();) { LLVector3 a(0.f, 0.f, 0.f); LLViewerPart* part = mParticles[i] ; dt = lastdt + mSkippedTime - part->mSkipOffset; part->mSkipOffset = 0.f; // Update current time const F32 cur_time = part->mLastUpdateTime + dt; const F32 frac = cur_time / part->mMaxAge; // "Drift" the object based on the source object if (part->mFlags & LLPartData::LL_PART_FOLLOW_SRC_MASK) { part->mPosAgent = part->mPartSourcep->mPosAgent; part->mPosAgent += part->mPosOffset; } // Do a custom callback if we have one... if (part->mVPCallback) { (*part->mVPCallback)(*part, dt); } if (part->mFlags & LLPartData::LL_PART_WIND_MASK) { LLVector3 tempVel(part->mVelocity); part->mVelocity *= 1.f - 0.1f*dt; part->mVelocity += 0.1f*dt*regionp->mWind.getVelocity(regionp->getPosRegionFromAgent(part->mPosAgent)); } // Now do interpolation towards a target if (part->mFlags & LLPartData::LL_PART_TARGET_POS_MASK) { F32 remaining = part->mMaxAge - part->mLastUpdateTime; F32 step = dt / remaining; step = llclamp(step, 0.f, 0.1f); step *= 5.f; // we want a velocity that will result in reaching the target in the // Interpolate towards the target. LLVector3 delta_pos = part->mPartSourcep->mTargetPosAgent - part->mPosAgent; delta_pos /= remaining; part->mVelocity *= (1.f - step); part->mVelocity += step*delta_pos; } if (part->mFlags & LLPartData::LL_PART_TARGET_LINEAR_MASK) { LLVector3 delta_pos = part->mPartSourcep->mTargetPosAgent - part->mPartSourcep->mPosAgent; part->mPosAgent = part->mPartSourcep->mPosAgent; part->mPosAgent += frac*delta_pos; part->mVelocity = delta_pos; } else { // Do velocity interpolation part->mPosAgent += dt*part->mVelocity; part->mPosAgent += 0.5f*dt*dt*part->mAccel; part->mVelocity += part->mAccel*dt; } // Do a bounce test if (part->mFlags & LLPartData::LL_PART_BOUNCE_MASK) { // Need to do point vs. plane check... // For now, just check relative to object height... F32 dz = part->mPosAgent.mV[VZ] - part->mPartSourcep->mPosAgent.mV[VZ]; if (dz < 0) { part->mPosAgent.mV[VZ] += -2.f*dz; part->mVelocity.mV[VZ] *= -0.75f; } } // Reset the offset from the source position if (part->mFlags & LLPartData::LL_PART_FOLLOW_SRC_MASK) { part->mPosOffset = part->mPosAgent; part->mPosOffset -= part->mPartSourcep->mPosAgent; } // Do color interpolation if (part->mFlags & LLPartData::LL_PART_INTERP_COLOR_MASK) { part->mColor.setVec(part->mStartColor); // note: LLColor4's v%k means multiply-alpha-only, // LLColor4's v*k means multiply-rgb-only part->mColor *= 1.f - frac; // rgb*k part->mColor %= 1.f - frac; // alpha*k part->mColor += frac%(frac*part->mEndColor); // rgb,alpha } // Do scale interpolation if (part->mFlags & LLPartData::LL_PART_INTERP_SCALE_MASK) { part->mScale.setVec(part->mStartScale); part->mScale *= 1.f - frac; part->mScale += frac*part->mEndScale; } // Set the last update time to now. part->mLastUpdateTime = cur_time; // Kill dead particles (either flagged dead, or too old) if ((part->mLastUpdateTime > part->mMaxAge) || (LLViewerPart::LL_PART_DEAD_MASK == part->mFlags)) { mParticles[i] = mParticles.back() ; mParticles.pop_back() ; delete part ; } else { F32 desired_size = calc_desired_size(part->mPosAgent, part->mScale); if (!posInGroup(part->mPosAgent, desired_size)) { // Transfer particles between groups LLViewerPartSim::getInstance()->put(part) ; mParticles[i] = mParticles.back() ; mParticles.pop_back() ; } else { i++ ; } } } S32 removed = end - (S32)mParticles.size(); if (removed > 0) { // we removed one or more particles, so flag this group for update if (mVOPartGroupp.notNull()) { gPipeline.markRebuild(mVOPartGroupp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); } LLViewerPartSim::decPartCount(removed); } // Kill the viewer object if this particle group is empty if (mParticles.empty()) { gObjectList.killObject(mVOPartGroupp); mVOPartGroupp = NULL; } }
void LLConsole::draw() { LLGLSUIDefault gls_ui; { LLMutexLock lock(&mQueueMutex); for(paragraph_t::iterator paragraph_it = mNewParagraphs.begin(); paragraph_it != mNewParagraphs.end(); paragraph_it++) { Paragraph* paragraph = *paragraph_it; mParagraphs.push_back(paragraph); paragraph->updateLines((F32)getRect().getWidth(), mFont); } mNewParagraphs.clear(); } if (mParagraphs.empty()) //No text to draw. { return; } // skip lines added more than mLinePersistTime ago F32 cur_time = mTimer.getElapsedTimeF32(); F32 skip_time = cur_time - mLinePersistTime; F32 fade_time = cur_time - mFadeTime; U32 max_lines = gSavedSettings.getS32("ConsoleMaxLines"); U32 num_lines=0; paragraph_t::reverse_iterator paragraph_it; paragraph_it = mParagraphs.rbegin(); U32 paragraph_num=mParagraphs.size(); while (!mParagraphs.empty() && paragraph_it != mParagraphs.rend()) { num_lines += (*paragraph_it)->mLines.size(); if(num_lines > max_lines || ( (mLinePersistTime > (F32)0.f) && ((*paragraph_it)->mAddTime - skip_time)/(mLinePersistTime - mFadeTime) <= (F32)0.f)) { //All lines above here are done. Lose them. for (U32 i=0;i<paragraph_num;i++) { if (!mParagraphs.empty()) { Paragraph* paragraph = mParagraphs.front(); mParagraphs.pop_front(); delete paragraph; } } break; } paragraph_num--; paragraph_it++; } if (mParagraphs.empty()) { return; } // draw remaining lines F32 y_pos = 0.f; LLUIImagePtr imagep = LLUI::getUIImage("rounded_square.tga"); F32 console_opacity = llclamp(gSavedSettings.getF32("ConsoleBackgroundOpacity"), 0.f, 1.f); LLColor4 color = gColors.getColor("ConsoleBackground"); color.mV[VALPHA] *= console_opacity; F32 line_height = mFont->getLineHeight(); S32 message_spacing = 0; //080813 Spatters: This section makes a single huge black box behind all the text. S32 bkg_height=8; S32 bkg_width=0; // VWR-8999 // ChatSpacing: 0 -- chat lines are close together, as they were in the 1.20 viewer. // 4 -- chat lines are farther apart as they are in SnowGlobe 1.4. static LLCachedControl<S32> chat_spacing("ChatSpacing", 0); // Perform clamping. S32 const clamped_chat_spacing = llclamp((S32)chat_spacing, -16, 128); if (chat_spacing != clamped_chat_spacing) { gSavedSettings.setS32("ChatSpacing", clamped_chat_spacing); } // Adjust spacing. message_spacing += chat_spacing; bkg_height -= chat_spacing; for(paragraph_it = mParagraphs.rbegin(); paragraph_it != mParagraphs.rend(); paragraph_it++) { S32 target_height = llfloor( (*paragraph_it)->mLines.size() * line_height + message_spacing); S32 target_width = llfloor( (*paragraph_it)->mMaxWidth + CONSOLE_GUTTER_RIGHT); bkg_height+= target_height; if (target_width > bkg_width) { bkg_width=target_width; } // Why is this not using llfloor as above? y_pos += ((*paragraph_it)->mLines.size()) * line_height; y_pos += message_spacing; //Extra spacing between messages. } imagep->drawSolid(-CONSOLE_GUTTER_LEFT, (S32)(y_pos + line_height - bkg_height - message_spacing), bkg_width, bkg_height, color); y_pos = 0.f; //End screen-eating black void for(paragraph_it = mParagraphs.rbegin(); paragraph_it != mParagraphs.rend(); paragraph_it++) { //080813 Spatters: Dainty per-message block boxes // S32 target_height = llfloor( (*paragraph_it)->mLines.size() * line_height + 8); S32 target_width = llfloor( (*paragraph_it)->mMaxWidth + CONSOLE_GUTTER_RIGHT); y_pos += ((*paragraph_it)->mLines.size()) * line_height; //080813 Spatters: Dainty per-message block boxes // imagep->drawSolid(-14, (S32)(y_pos + line_height - target_height), target_width, target_height, color); F32 y_off=0; F32 alpha; if ((mLinePersistTime > 0.f) && ((*paragraph_it)->mAddTime < fade_time)) { alpha = ((*paragraph_it)->mAddTime - skip_time)/(mLinePersistTime - mFadeTime); } else { alpha = 1.0f; } if( alpha > 0.f ) { for (lines_t::iterator line_it=(*paragraph_it)->mLines.begin(); line_it != (*paragraph_it)->mLines.end(); line_it ++) { for (line_color_segments_t::iterator seg_it = (*line_it).begin(); seg_it != (*line_it).end(); seg_it++) { mFont->render((*seg_it).mText, 0, (*seg_it).mXPosition - 8, y_pos - y_off, LLColor4( (*seg_it).mColor.mV[VRED], (*seg_it).mColor.mV[VGREEN], (*seg_it).mColor.mV[VBLUE], (*seg_it).mColor.mV[VALPHA]*alpha), LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::DROP_SHADOW, S32_MAX, target_width ); } y_off += line_height; } } y_pos += message_spacing; //Extra spacing between messages. } }
void LLComboBox::showList() { // Make sure we don't go off top of screen. LLCoordWindow window_size; getWindow()->getSize(&window_size); //HACK: shouldn't have to know about scale here mList->fitContents( 192, llfloor((F32)window_size.mY / LLUI::sGLScaleFactor.mV[VY]) - 50 ); // Make sure that we can see the whole list LLRect root_view_local; LLView* root_view = getRootView(); root_view->localRectToOtherView(root_view->getLocalRect(), &root_view_local, this); LLRect rect = mList->getRect(); S32 min_width = getRect().getWidth(); S32 max_width = llmax(min_width, MAX_COMBO_WIDTH); // make sure we have up to date content width metrics mList->calcColumnWidths(); S32 list_width = llclamp(mList->getMaxContentWidth(), min_width, max_width); if (mListPosition == BELOW) { if (rect.getHeight() <= -root_view_local.mBottom) { // Move rect so it hangs off the bottom of this view rect.setLeftTopAndSize(0, 0, list_width, rect.getHeight() ); } else { // stack on top or bottom, depending on which has more room if (-root_view_local.mBottom > root_view_local.mTop - getRect().getHeight()) { // Move rect so it hangs off the bottom of this view rect.setLeftTopAndSize(0, 0, list_width, llmin(-root_view_local.mBottom, rect.getHeight())); } else { // move rect so it stacks on top of this view (clipped to size of screen) rect.setOriginAndSize(0, getRect().getHeight(), list_width, llmin(root_view_local.mTop - getRect().getHeight(), rect.getHeight())); } } } else // ABOVE { if (rect.getHeight() <= root_view_local.mTop - getRect().getHeight()) { // move rect so it stacks on top of this view (clipped to size of screen) rect.setOriginAndSize(0, getRect().getHeight(), list_width, llmin(root_view_local.mTop - getRect().getHeight(), rect.getHeight())); } else { // stack on top or bottom, depending on which has more room if (-root_view_local.mBottom > root_view_local.mTop - getRect().getHeight()) { // Move rect so it hangs off the bottom of this view rect.setLeftTopAndSize(0, 0, list_width, llmin(-root_view_local.mBottom, rect.getHeight())); } else { // move rect so it stacks on top of this view (clipped to size of screen) rect.setOriginAndSize(0, getRect().getHeight(), list_width, llmin(root_view_local.mTop - getRect().getHeight(), rect.getHeight())); } } } mList->setOrigin(rect.mLeft, rect.mBottom); mList->reshape(rect.getWidth(), rect.getHeight()); mList->translateIntoRect(root_view_local, FALSE); // Make sure we didn't go off bottom of screen S32 x, y; mList->localPointToScreen(0, 0, &x, &y); if (y < 0) { mList->translate(0, -y); } // NB: this call will trigger the focuslost callback which will hide the list, so do it first // before finally showing the list mList->setFocus(TRUE); // register ourselves as a "top" control // effectively putting us into a special draw layer // and not affecting the bounding rectangle calculation gFocusMgr.setTopCtrl(this); // Show the list and push the button down mButton->setToggleState(TRUE); mList->setVisible(TRUE); setUseBoundingRect(TRUE); }
//----------------------------------------------------------------------------- // zoom() //----------------------------------------------------------------------------- void LLImagePreviewSculpted::zoom(F32 zoom_amt) { mCameraZoom = llclamp(mCameraZoom + zoom_amt, 1.f, 10.f); }
//----------------------------------------------------------------------------- // rotate() //----------------------------------------------------------------------------- void LLImagePreviewSculpted::rotate(F32 yaw_radians, F32 pitch_radians) { mCameraYaw = mCameraYaw + yaw_radians; mCameraPitch = llclamp(mCameraPitch + pitch_radians, F_PI_BY_TWO * -0.8f, F_PI_BY_TWO * 0.8f); }
void LLImagePreviewAvatar::pan(F32 right, F32 up) { mCameraOffset.mV[VY] = llclamp(mCameraOffset.mV[VY] + right * mCameraDistance / mCameraZoom, -1.f, 1.f); mCameraOffset.mV[VZ] = llclamp(mCameraOffset.mV[VZ] + up * mCameraDistance / mCameraZoom, -1.f, 1.f); }
//----------------------------------------------------------------------------- // setZoom() //----------------------------------------------------------------------------- void LLPreviewAnimation::setZoom(F32 zoom_amt) { mCameraZoom = llclamp(zoom_amt, MIN_CAMERA_ZOOM, MAX_CAMERA_ZOOM); }
F32 calc_desired_size(LLVector3 pos, LLVector2 scale) { F32 desired_size = (pos-LLViewerCamera::getInstance()->getOrigin()).magVec(); desired_size /= 4; return llclamp(desired_size, scale.magVec()*0.5f, PART_SIM_BOX_SIDE*2); }
// Paint the display! void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { LLFastTimer t(LLFastTimer::FTM_RENDER); if (LLPipeline::sRenderFrameTest) { send_agent_pause(); } gSnapshot = for_snapshot; LLGLSDefault gls_default; LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE, GL_LEQUAL); LLVertexBuffer::unbind(); LLGLState::checkStates(); LLGLState::checkTextureChannels(); 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(); } gViewerWindow->returnEmptyPicks(); return; } gViewerWindow->checkSettings(); { LLFastTimer ftm(LLFastTimer::FTM_PICK); LLAppViewer::instance()->pingMainloopTimeout("Display:Pick"); gViewerWindow->performPick(); } LLAppViewer::instance()->pingMainloopTimeout("Display:CheckStates"); LLGLState::checkStates(); LLGLState::checkTextureChannels(); ////////////////////////////////////////////////////////// // // 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) { LLAppViewer::instance()->pingMainloopTimeout("Display:Startup"); display_startup(); return; } //LLGLState::verify(FALSE); ///////////////////////////////////////////////// // // Update GL Texture statistics (used for discard logic?) // LLAppViewer::instance()->pingMainloopTimeout("Display:TextureStats"); gFrameStats.start(LLFrameStats::UPDATE_TEX_STATS); stop_glerror(); LLImageGL::updateStats(gFrameTimeSeconds); LLVOAvatar::sRenderName = gSavedSettings.getS32("RenderName"); LLVOAvatar::sRenderGroupTitles = !gSavedSettings.getBOOL("RenderHideGroupTitleAll"); gPipeline.mBackfaceCull = TRUE; gFrameCount++; gRecentFrameCount++; if (gFocusMgr.getAppHasFocus()) { gForegroundFrameCount++; } ////////////////////////////////////////////////////////// // // Display start screen if we're teleporting, and skip render // if (gTeleportDisplay) { LLAppViewer::instance()->pingMainloopTimeout("Display:Teleport"); 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(std::string()); } const std::string& 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, std::string("Cancel")); //TODO: Translate gViewerWindow->setProgressPercent(75.f); gAgent.setTeleportState( LLAgent::TELEPORT_ARRIVING ); gAgent.setTeleportMessage( LLAgent::sTeleportProgressMessages["arriving"]); gImageList.mForceResetTextureStats = TRUE; gAgent.resetView(TRUE, 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; LLFirstUse::useTeleport(); gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); } gViewerWindow->setProgressCancelButtonVisible(FALSE, std::string("Cancel")); //TODO: Translate gViewerWindow->setProgressPercent( arrival_fraction * 25.f + 75.f); gViewerWindow->setProgressString(message); } break; case LLAgent::TELEPORT_LOCAL: // Short delay when teleporting in the same sim (progress screen active but not shown - did not // fall-through from TELEPORT_START) { if( gTeleportDisplayTimer.getElapsedTimeF32() > TELEPORT_LOCAL_DELAY ) { LLFirstUse::useTeleport(); gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); } } break; case LLAgent::TELEPORT_NONE: // No teleport in progress gViewerWindow->setShowProgress(FALSE); gTeleportDisplay = FALSE; break; default: break; } } else if(LLAppViewer::instance()->logoutRequestSent()) { LLAppViewer::instance()->pingMainloopTimeout("Display:Logout"); 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) { LLAppViewer::instance()->pingMainloopTimeout("Display:RestoreGL"); 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 // ///////////////////////////// // // Update the camera // // LLAppViewer::instance()->pingMainloopTimeout("Display:Camera"); LLViewerCamera::getInstance()->setZoomParameters(zoom_factor, subfield); LLViewerCamera::getInstance()->setNear(MIN_NEAR_PLANE); ////////////////////////// // // clear the next buffer // (must follow dynamic texture writing since that uses the frame buffer) // if (gDisconnected) { LLAppViewer::instance()->pingMainloopTimeout("Display:Disconnected"); render_ui(); render_disconnected_background(); } ////////////////////////// // // Set rendering options // // LLAppViewer::instance()->pingMainloopTimeout("Display:RenderSetup"); 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(); ///////////////////////////////////// // // Render // // Actually push all of our triangles to the screen. // // do render-to-texture stuff here if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES)) { LLAppViewer::instance()->pingMainloopTimeout("Display:DynamicTextures"); LLFastTimer t(LLFastTimer::FTM_UPDATE_TEXTURES); if (LLDynamicTexture::updateAllInstances()) { gGL.setColorMask(true, true); glClear(GL_DEPTH_BUFFER_BIT); } } gViewerWindow->setupViewport(); gPipeline.resetFrameStats(); // Reset per-frame statistics. if (!gDisconnected) { LLAppViewer::instance()->pingMainloopTimeout("Display:Update"); if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) { //don't draw hud objects in this frame gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); } if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES)) { //don't draw hud particles in this frame gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES); } //upkeep gl name pools LLGLNamePool::upkeepPools(); stop_glerror(); display_update_camera(); stop_glerror(); // *TODO: merge these two methods LLHUDManager::getInstance()->updateEffects(); LLHUDObject::updateAll(); stop_glerror(); gFrameStats.start(LLFrameStats::UPDATE_GEOM); const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds; // 50 ms/second update time gPipeline.createObjects(max_geom_update_time); gPipeline.updateGeom(max_geom_update_time); stop_glerror(); gFrameStats.start(LLFrameStats::UPDATE_CULL); S32 water_clip = 0; if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT) > 1) && (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER) || gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_VOIDWATER))) { if (LLViewerCamera::getInstance()->cameraUnderWater()) { water_clip = -1; } else { water_clip = 1; } } LLAppViewer::instance()->pingMainloopTimeout("Display:Cull"); //Increment drawable frame counter LLDrawable::incrementVisible(); LLSpatialGroup::sNoDelete = TRUE; LLPipeline::sUseOcclusion = (!gUseWireframe && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") && gSavedSettings.getBOOL("UseOcclusion") && gGLManager.mHasOcclusionQuery) ? 2 : 0; if (LLPipeline::sUseOcclusion && LLPipeline::sRenderDeferred) { //force occlusion on for all render types if doing deferred render LLPipeline::sUseOcclusion = 3; } LLPipeline::sFastAlpha = gSavedSettings.getBOOL("RenderFastAlpha"); LLPipeline::sUseFarClip = gSavedSettings.getBOOL("RenderUseFarClip"); LLVOAvatar::sMaxVisible = gSavedSettings.getS32("RenderAvatarMaxVisible"); LLPipeline::sDelayVBUpdate = gSavedSettings.getBOOL("RenderDelayVBUpdate"); S32 occlusion = LLPipeline::sUseOcclusion; if (gDepthDirty) { //depth buffer is invalid, don't overwrite occlusion state LLPipeline::sUseOcclusion = llmin(occlusion, 1); } gDepthDirty = FALSE; LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); static LLCullResult result; gPipeline.updateCull(*LLViewerCamera::getInstance(), result, water_clip); stop_glerror(); LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); BOOL to_texture = !for_snapshot && gPipeline.canUseVertexShaders() && LLPipeline::sRenderGlow; LLAppViewer::instance()->pingMainloopTimeout("Display:Swap"); { { LLFastTimer ftm(LLFastTimer::FTM_CLIENT_COPY); LLVertexBuffer::clientCopy(0.016); } if (gResizeScreenTexture) { gResizeScreenTexture = FALSE; gPipeline.resizeScreenTexture(); } gGL.setColorMask(true, true); glClearColor(0,0,0,0); LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); if (!for_snapshot) { if (gFrameCount > 1) { //for some reason, ATI 4800 series will error out if you //try to generate a shadow before the first frame is through gPipeline.generateSunShadow(*LLViewerCamera::getInstance()); } LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); glh::matrix4f proj = glh_get_current_projection(); glh::matrix4f mod = glh_get_current_modelview(); glViewport(0,0,512,512); LLVOAvatar::updateFreezeCounter() ; LLVOAvatar::updateImpostors(); glh_set_current_projection(proj); glh_set_current_modelview(mod); glMatrixMode(GL_PROJECTION); glLoadMatrixf(proj.m); glMatrixMode(GL_MODELVIEW); glLoadMatrixf(mod.m); gViewerWindow->setupViewport(); LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); } glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); } if (!for_snapshot) { LLAppViewer::instance()->pingMainloopTimeout("Display:Imagery"); gPipeline.generateWaterReflection(*LLViewerCamera::getInstance()); } ////////////////////////////////////// // // Update images, using the image stats generated during object update/culling // // Can put objects onto the retextured list. // // Doing this here gives hardware occlusion queries extra time to complete LLAppViewer::instance()->pingMainloopTimeout("Display:UpdateImages"); LLError::LLCallStacks::clear() ; llpushcallstacks ; gFrameStats.start(LLFrameStats::IMAGE_UPDATE); { LLFastTimer t(LLFastTimer::FTM_IMAGE_UPDATE); LLViewerImage::updateClass(LLViewerCamera::getInstance()->getVelocityStat()->getMean(), LLViewerCamera::getInstance()->getAngularVelocityStat()->getMean()); gBumpImageList.updateImages(); // must be called before gImageList version so that it's textures are thrown out first. F32 max_image_decode_time = 0.050f*gFrameIntervalSeconds; // 50 ms/second decode time max_image_decode_time = llclamp(max_image_decode_time, 0.001f, 0.005f ); // min 1ms/frame, max 5ms/frame) gImageList.updateImages(max_image_decode_time); stop_glerror(); } llpushcallstacks ; /////////////////////////////////// // // 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. // LLAppViewer::instance()->pingMainloopTimeout("Display:StateSort"); { gFrameStats.start(LLFrameStats::STATE_SORT); gPipeline.stateSort(*LLViewerCamera::getInstance(), result); stop_glerror(); if (rebuild) { ////////////////////////////////////// // // rebuildPools // // gFrameStats.start(LLFrameStats::REBUILD); gPipeline.rebuildPools(); stop_glerror(); } } LLPipeline::sUseOcclusion = occlusion; { LLAppViewer::instance()->pingMainloopTimeout("Display:Sky"); LLFastTimer t(LLFastTimer::FTM_UPDATE_SKY); gSky.updateSky(); } if(gUseWireframe) { glClearColor(0.5f, 0.5f, 0.5f, 0.f); glClear(GL_COLOR_BUFFER_BIT); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } LLAppViewer::instance()->pingMainloopTimeout("Display:RenderStart"); //// 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(); // { // gGL.getTexUnit(0)->unbind(LLTexUnit::TT_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, -LLViewerCamera::getInstance()->getNear()); // glScalef(LLViewerCamera::getInstance()->getNear() * LLViewerCamera::getInstance()->getAspect() / sinf(LLViewerCamera::getInstance()->getView()), LLViewerCamera::getInstance()->getNear() / sinf(LLViewerCamera::getInstance()->getView()), 1.f); // gGL.color4fv(LLColor4::white.mV); // gGL.begin(LLVertexBuffer::QUADS); // { // gGL.vertex3f(floater_3d_rect.mLeft, floater_3d_rect.mBottom, 0.f); // gGL.vertex3f(floater_3d_rect.mLeft, floater_3d_rect.mTop, 0.f); // gGL.vertex3f(floater_3d_rect.mRight, floater_3d_rect.mTop, 0.f); // gGL.vertex3f(floater_3d_rect.mRight, floater_3d_rect.mBottom, 0.f); // } // gGL.end(); // glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // } // glPopMatrix(); //} LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE; //Check for RenderWater if (!gSavedSettings.getBOOL("RenderWater")) LLPipeline::sUnderWaterRender = FALSE; LLPipeline::updateRenderDeferred(); stop_glerror(); if (to_texture) { gGL.setColorMask(true, true); if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) { gPipeline.mDeferredScreen.bindTarget(); gPipeline.mDeferredScreen.clear(); } else { gPipeline.mScreen.bindTarget(); gPipeline.mScreen.clear(); } gGL.setColorMask(true, false); } LLAppViewer::instance()->pingMainloopTimeout("Display:RenderGeom"); if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot()) && !gRestoreGL) { gGL.setColorMask(true, false); if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) { gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance()); } else { gPipeline.renderGeom(*LLViewerCamera::getInstance(), TRUE); } gGL.setColorMask(true, true); //store this frame's modelview matrix for use //when rendering next frame's occlusion queries for (U32 i = 0; i < 16; i++) { gGLLastModelView[i] = gGLModelView[i]; } stop_glerror(); } LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush"); if (to_texture) { if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) { gPipeline.mDeferredScreen.flush(); } else { gPipeline.mScreen.flush(); } } /// We copy the frame buffer straight into a texture here, /// and then display it again with compositor effects. /// Using render to texture would be faster/better, but I don't have a /// grasp of their full display stack just yet. // gPostProcess->apply(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight()); if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) { gPipeline.renderDeferredLighting(); } LLPipeline::sUnderWaterRender = FALSE; LLAppViewer::instance()->pingMainloopTimeout("Display:RenderUI"); if (!for_snapshot) { gFrameStats.start(LLFrameStats::RENDER_UI); render_ui(); } LLSpatialGroup::sNoDelete = FALSE; } LLAppViewer::instance()->pingMainloopTimeout("Display:FrameStats"); gFrameStats.start(LLFrameStats::MISC_END); stop_glerror(); if (LLPipeline::sRenderFrameTest) { send_agent_resume(); LLPipeline::sRenderFrameTest = FALSE; } display_stats(); LLAppViewer::instance()->pingMainloopTimeout("Display:Done"); }
// Compute target jpeg quality : see https://wiki.lindenlab.com/wiki/Facebook_Image_Quality for details S32 compute_jpeg_quality(S32 width, S32 height) { F32 target_compression_ratio = (F32)(width * height * 3) / (F32)(TARGET_DATA_SIZE); S32 quality = (S32)(110.0f - (2.0f * target_compression_ratio)); return llclamp(quality,MIN_QUALITY,MAX_QUALITY); }
LLVector3d LLWorld::clipToVisibleRegions(const LLVector3d &start_pos, const LLVector3d &end_pos) { if (positionRegionValidGlobal(end_pos)) { return end_pos; } LLViewerRegion* regionp = getRegionFromPosGlobal(start_pos); if (!regionp) { return start_pos; } LLVector3d delta_pos = end_pos - start_pos; LLVector3d delta_pos_abs; delta_pos_abs.setVec(delta_pos); delta_pos_abs.abs(); LLVector3 region_coord = regionp->getPosRegionFromGlobal(end_pos); F64 clip_factor = 1.0; F32 region_width = regionp->getWidth(); if (region_coord.mV[VX] < 0.f) { if (region_coord.mV[VY] < region_coord.mV[VX]) { // clip along y - clip_factor = -(region_coord.mV[VY] / delta_pos_abs.mdV[VY]); } else { // clip along x - clip_factor = -(region_coord.mV[VX] / delta_pos_abs.mdV[VX]); } } else if (region_coord.mV[VX] > region_width) { if (region_coord.mV[VY] > region_coord.mV[VX]) { // clip along y + clip_factor = (region_coord.mV[VY] - region_width) / delta_pos_abs.mdV[VY]; } else { //clip along x + clip_factor = (region_coord.mV[VX] - region_width) / delta_pos_abs.mdV[VX]; } } else if (region_coord.mV[VY] < 0.f) { // clip along y - clip_factor = -(region_coord.mV[VY] / delta_pos_abs.mdV[VY]); } else if (region_coord.mV[VY] > region_width) { // clip along y + clip_factor = (region_coord.mV[VY] - region_width) / delta_pos_abs.mdV[VY]; } // clamp to within region dimensions LLVector3d final_region_pos = LLVector3d(region_coord) - (delta_pos * clip_factor); final_region_pos.mdV[VX] = llclamp(final_region_pos.mdV[VX], 0.0, (F64)(region_width - F_ALMOST_ZERO)); final_region_pos.mdV[VY] = llclamp(final_region_pos.mdV[VY], 0.0, (F64)(region_width - F_ALMOST_ZERO)); final_region_pos.mdV[VZ] = llclamp(final_region_pos.mdV[VZ], 0.0, (F64)(gHippoLimits->getMaxHeight() - F_ALMOST_ZERO));//from hippo limits //(F64)(LLWorld::getInstance()-> gHippoLimits->getMaxHeight() - F_ALMOST_ZERO));//from hippo limits return regionp->getPosGlobalFromRegion(LLVector3(final_region_pos)); }
void LLSaleInfo::setSalePrice(S32 price) { mSalePrice = price; mSalePrice = llclamp(mSalePrice, 0, S32_MAX); }
//----------------------------------------------------------------------------- // zoom() //----------------------------------------------------------------------------- void LLPreviewAvatar::zoom(F32 zoom_amt) { mCameraZoom = llclamp(mCameraZoom + zoom_amt, 0.5f, 20.f); }
LLSaleInfo::LLSaleInfo(EForSale sale_type, S32 sale_price) : mSaleType(sale_type), mSalePrice(sale_price) { mSalePrice = llclamp(mSalePrice, 0, S32_MAX); }
//----------------------------------------------------------------------------- // zoom() //----------------------------------------------------------------------------- void LLPreviewSculpted::zoom(F32 zoom_amt) { mCameraZoom = llclamp(mCameraZoom + zoom_amt, 0.5f, 20.f); }
// Sets all libcurl options and data for a request. // // Used both for initial requests and to 'reload' for // a retry, generally with a different CURL handle. // Junk may be left around from a failed request and that // needs to be cleaned out. // HttpStatus HttpOpRequest::prepareRequest(HttpService * service) { CURLcode code; // Scrub transport and result data for retried op case mCurlActive = false; mCurlHandle = NULL; mCurlService = NULL; if (mCurlHeaders) { curl_slist_free_all(mCurlHeaders); mCurlHeaders = NULL; } mCurlBodyPos = 0; if (mReplyBody) { mReplyBody->release(); mReplyBody = NULL; } mReplyOffset = 0; mReplyLength = 0; mReplyFullLength = 0; if (mReplyHeaders) { mReplyHeaders->release(); mReplyHeaders = NULL; } mReplyConType.clear(); // *FIXME: better error handling later HttpStatus status; // Get global policy options HttpPolicyGlobal & policy(service->getPolicy().getGlobalOptions()); mCurlHandle = LLCurl::createStandardCurlHandle(); if (! mCurlHandle) { // We're in trouble. We'll continue but it won't go well. LL_WARNS("CoreHttp") << "Failed to allocate libcurl easy handle. Continuing." << LL_ENDL; return HttpStatus(HttpStatus::LLCORE, HE_BAD_ALLOC); } code = curl_easy_setopt(mCurlHandle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); check_curl_easy_code(code, CURLOPT_IPRESOLVE); code = curl_easy_setopt(mCurlHandle, CURLOPT_NOSIGNAL, 1); check_curl_easy_code(code, CURLOPT_NOSIGNAL); code = curl_easy_setopt(mCurlHandle, CURLOPT_NOPROGRESS, 1); check_curl_easy_code(code, CURLOPT_NOPROGRESS); code = curl_easy_setopt(mCurlHandle, CURLOPT_URL, mReqURL.c_str()); check_curl_easy_code(code, CURLOPT_URL); code = curl_easy_setopt(mCurlHandle, CURLOPT_PRIVATE, this); check_curl_easy_code(code, CURLOPT_PRIVATE); code = curl_easy_setopt(mCurlHandle, CURLOPT_ENCODING, ""); check_curl_easy_code(code, CURLOPT_ENCODING); // The Linksys WRT54G V5 router has an issue with frequent // DNS lookups from LAN machines. If they happen too often, // like for every HTTP request, the router gets annoyed after // about 700 or so requests and starts issuing TCP RSTs to // new connections. Reuse the DNS lookups for even a few // seconds and no RSTs. code = curl_easy_setopt(mCurlHandle, CURLOPT_DNS_CACHE_TIMEOUT, 15); check_curl_easy_code(code, CURLOPT_DNS_CACHE_TIMEOUT); code = curl_easy_setopt(mCurlHandle, CURLOPT_AUTOREFERER, 1); check_curl_easy_code(code, CURLOPT_AUTOREFERER); code = curl_easy_setopt(mCurlHandle, CURLOPT_FOLLOWLOCATION, 1); check_curl_easy_code(code, CURLOPT_FOLLOWLOCATION); code = curl_easy_setopt(mCurlHandle, CURLOPT_MAXREDIRS, HTTP_REDIRECTS_DEFAULT); check_curl_easy_code(code, CURLOPT_MAXREDIRS); code = curl_easy_setopt(mCurlHandle, CURLOPT_WRITEFUNCTION, writeCallback); check_curl_easy_code(code, CURLOPT_WRITEFUNCTION); code = curl_easy_setopt(mCurlHandle, CURLOPT_WRITEDATA, this); check_curl_easy_code(code, CURLOPT_WRITEDATA); code = curl_easy_setopt(mCurlHandle, CURLOPT_READFUNCTION, readCallback); check_curl_easy_code(code, CURLOPT_READFUNCTION); code = curl_easy_setopt(mCurlHandle, CURLOPT_READDATA, this); check_curl_easy_code(code, CURLOPT_READDATA); code = curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYPEER, 1); check_curl_easy_code(code, CURLOPT_SSL_VERIFYPEER); code = curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYHOST, 0); check_curl_easy_code(code, CURLOPT_SSL_VERIFYHOST); if (policy.mUseLLProxy) { // Use the viewer-based thread-safe API which has a // fast/safe check for proxy enable. Would like to // encapsulate this someway... LLProxy::getInstance()->applyProxySettings(mCurlHandle); } else if (policy.mHttpProxy.size()) { // *TODO: This is fine for now but get fuller socks5/ // authentication thing going later.... code = curl_easy_setopt(mCurlHandle, CURLOPT_PROXY, policy.mHttpProxy.c_str()); check_curl_easy_code(code, CURLOPT_PROXY); code = curl_easy_setopt(mCurlHandle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); check_curl_easy_code(code, CURLOPT_PROXYTYPE); } if (policy.mCAPath.size()) { code = curl_easy_setopt(mCurlHandle, CURLOPT_CAPATH, policy.mCAPath.c_str()); check_curl_easy_code(code, CURLOPT_CAPATH); } if (policy.mCAFile.size()) { code = curl_easy_setopt(mCurlHandle, CURLOPT_CAINFO, policy.mCAFile.c_str()); check_curl_easy_code(code, CURLOPT_CAINFO); } switch (mReqMethod) { case HOR_GET: code = curl_easy_setopt(mCurlHandle, CURLOPT_HTTPGET, 1); check_curl_easy_code(code, CURLOPT_HTTPGET); mCurlHeaders = curl_slist_append(mCurlHeaders, "Connection: keep-alive"); mCurlHeaders = curl_slist_append(mCurlHeaders, "Keep-alive: 300"); break; case HOR_POST: { code = curl_easy_setopt(mCurlHandle, CURLOPT_POST, 1); check_curl_easy_code(code, CURLOPT_POST); code = curl_easy_setopt(mCurlHandle, CURLOPT_ENCODING, ""); check_curl_easy_code(code, CURLOPT_ENCODING); long data_size(0); if (mReqBody) { data_size = mReqBody->size(); } code = curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDS, static_cast<void *>(NULL)); check_curl_easy_code(code, CURLOPT_POSTFIELDS); code = curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDSIZE, data_size); check_curl_easy_code(code, CURLOPT_POSTFIELDSIZE); mCurlHeaders = curl_slist_append(mCurlHeaders, "Expect:"); mCurlHeaders = curl_slist_append(mCurlHeaders, "Connection: keep-alive"); mCurlHeaders = curl_slist_append(mCurlHeaders, "Keep-alive: 300"); } break; case HOR_PUT: { code = curl_easy_setopt(mCurlHandle, CURLOPT_UPLOAD, 1); check_curl_easy_code(code, CURLOPT_UPLOAD); long data_size(0); if (mReqBody) { data_size = mReqBody->size(); } code = curl_easy_setopt(mCurlHandle, CURLOPT_INFILESIZE, data_size); check_curl_easy_code(code, CURLOPT_INFILESIZE); code = curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDS, (void *) NULL); check_curl_easy_code(code, CURLOPT_POSTFIELDS); mCurlHeaders = curl_slist_append(mCurlHeaders, "Expect:"); mCurlHeaders = curl_slist_append(mCurlHeaders, "Connection: keep-alive"); mCurlHeaders = curl_slist_append(mCurlHeaders, "Keep-alive: 300"); } break; default: LL_ERRS("CoreHttp") << "Invalid HTTP method in request: " << int(mReqMethod) << ". Can't recover." << LL_ENDL; break; } // Tracing if (mTracing >= HTTP_TRACE_CURL_HEADERS) { code = curl_easy_setopt(mCurlHandle, CURLOPT_VERBOSE, 1); check_curl_easy_code(code, CURLOPT_VERBOSE); code = curl_easy_setopt(mCurlHandle, CURLOPT_DEBUGDATA, this); check_curl_easy_code(code, CURLOPT_DEBUGDATA); code = curl_easy_setopt(mCurlHandle, CURLOPT_DEBUGFUNCTION, debugCallback); check_curl_easy_code(code, CURLOPT_DEBUGFUNCTION); } // There's a CURLOPT for this now... if ((mReqOffset || mReqLength) && HOR_GET == mReqMethod) { static const char * const fmt1("Range: bytes=%lu-%lu"); static const char * const fmt2("Range: bytes=%lu-"); char range_line[64]; #if LL_WINDOWS _snprintf_s(range_line, sizeof(range_line), sizeof(range_line) - 1, (mReqLength ? fmt1 : fmt2), (unsigned long) mReqOffset, (unsigned long) (mReqOffset + mReqLength - 1)); #else snprintf(range_line, sizeof(range_line), (mReqLength ? fmt1 : fmt2), (unsigned long) mReqOffset, (unsigned long) (mReqOffset + mReqLength - 1)); #endif // LL_WINDOWS range_line[sizeof(range_line) - 1] = '\0'; mCurlHeaders = curl_slist_append(mCurlHeaders, range_line); } mCurlHeaders = curl_slist_append(mCurlHeaders, "Pragma:"); // Request options long timeout(HTTP_REQUEST_TIMEOUT_DEFAULT); long xfer_timeout(HTTP_REQUEST_XFER_TIMEOUT_DEFAULT); if (mReqOptions) { timeout = mReqOptions->getTimeout(); timeout = llclamp(timeout, HTTP_REQUEST_TIMEOUT_MIN, HTTP_REQUEST_TIMEOUT_MAX); xfer_timeout = mReqOptions->getTransferTimeout(); xfer_timeout = llclamp(xfer_timeout, HTTP_REQUEST_TIMEOUT_MIN, HTTP_REQUEST_TIMEOUT_MAX); } if (xfer_timeout == 0L) { xfer_timeout = timeout; } code = curl_easy_setopt(mCurlHandle, CURLOPT_TIMEOUT, xfer_timeout); check_curl_easy_code(code, CURLOPT_TIMEOUT); code = curl_easy_setopt(mCurlHandle, CURLOPT_CONNECTTIMEOUT, timeout); check_curl_easy_code(code, CURLOPT_CONNECTTIMEOUT); // Request headers if (mReqHeaders) { // Caller's headers last to override mCurlHeaders = append_headers_to_slist(mReqHeaders, mCurlHeaders); } code = curl_easy_setopt(mCurlHandle, CURLOPT_HTTPHEADER, mCurlHeaders); check_curl_easy_code(code, CURLOPT_HTTPHEADER); if (mProcFlags & (PF_SCAN_RANGE_HEADER | PF_SAVE_HEADERS | PF_USE_RETRY_AFTER)) { code = curl_easy_setopt(mCurlHandle, CURLOPT_HEADERFUNCTION, headerCallback); check_curl_easy_code(code, CURLOPT_HEADERFUNCTION); code = curl_easy_setopt(mCurlHandle, CURLOPT_HEADERDATA, this); check_curl_easy_code(code, CURLOPT_HEADERDATA); } if (status) { mCurlService = service; } return status; }
void LLImageTGA::decodeColorMapPixel8( U8* dst, const U8* src ) { S32 index = llclamp( *src - mColorMapStart, 0, mColorMapLength - 1 ); dst[0] = mColorMap[ index ]; }
void LLProgressView::setPercent(const F32 percent) { mPercentDone = llclamp(percent, 0.f, 100.f); }
void LLConsole::draw() { LLGLSUIDefault gls_ui; // skip lines added more than mLinePersistTime ago F32 cur_time = mTimer.getElapsedTimeF32(); F32 skip_time = cur_time - mLinePersistTime; F32 fade_time = cur_time - mFadeTime; if (mParagraphs.empty()) //No text to draw. { return; } U32 num_lines=0; paragraph_t::reverse_iterator paragraph_it; paragraph_it = mParagraphs.rbegin(); U32 paragraph_num=mParagraphs.size(); while (!mParagraphs.empty() && paragraph_it != mParagraphs.rend()) { num_lines += (*paragraph_it).mLines.size(); if(num_lines > mMaxLines || ( (mLinePersistTime > (F32)0.f) && ((*paragraph_it).mAddTime - skip_time)/(mLinePersistTime - mFadeTime) <= (F32)0.f)) { //All lines above here are done. Lose them. for (U32 i=0; i<paragraph_num; i++) { if (!mParagraphs.empty()) mParagraphs.pop_front(); } break; } paragraph_num--; paragraph_it++; } if (mParagraphs.empty()) { return; } // draw remaining lines F32 y_pos = 0.f; LLUIImagePtr imagep = LLUI::getUIImage("Rounded_Square"); // F32 console_opacity = llclamp(gSavedSettings.getF32("ConsoleBackgroundOpacity"), 0.f, 1.f); F32 console_opacity = llclamp(LLUI::sSettingGroups["config"]->getF32("ConsoleBackgroundOpacity"), 0.f, 1.f); // LLColor4 color = LLUIColorTable::instance().getColor("ConsoleBackground"); LLColor4 color = LLUIColorTable::instance().getColor("ConsoleBackground"); color.mV[VALPHA] *= console_opacity; F32 line_height = mFont->getLineHeight(); for(paragraph_it = mParagraphs.rbegin(); paragraph_it != mParagraphs.rend(); paragraph_it++) { S32 target_height = llfloor( (*paragraph_it).mLines.size() * line_height + 8); S32 target_width = llfloor( (*paragraph_it).mMaxWidth +15); y_pos += ((*paragraph_it).mLines.size()) * line_height; imagep->drawSolid(-14, (S32)(y_pos + line_height - target_height), target_width, target_height, color); F32 y_off=0; F32 alpha; if ((mLinePersistTime > 0.f) && ((*paragraph_it).mAddTime < fade_time)) { alpha = ((*paragraph_it).mAddTime - skip_time)/(mLinePersistTime - mFadeTime); } else { alpha = 1.0f; } if( alpha > 0.f ) { for (lines_t::iterator line_it=(*paragraph_it).mLines.begin(); line_it != (*paragraph_it).mLines.end(); line_it ++) { for (line_color_segments_t::iterator seg_it = (*line_it).mLineColorSegments.begin(); seg_it != (*line_it).mLineColorSegments.end(); seg_it++) { mFont->render((*seg_it).mText, 0, (*seg_it).mXPosition - 8, y_pos - y_off, LLColor4( (*seg_it).mColor.mV[VRED], (*seg_it).mColor.mV[VGREEN], (*seg_it).mColor.mV[VBLUE], (*seg_it).mColor.mV[VALPHA]*alpha), LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW, S32_MAX, target_width ); } y_off += line_height; } } y_pos += 8; } }
//----------------------------------------------------------------------------- // rotate() //----------------------------------------------------------------------------- void LLPreviewAnimation::rotate(F32 yaw_radians, F32 pitch_radians) { mCameraYaw = mCameraYaw + yaw_radians; mCameraPitch = llclamp(mCameraPitch + pitch_radians, F_PI_BY_TWO * -0.8f, F_PI_BY_TWO * 0.8f); }
LLSurfacePatch *LLSurface::resolvePatchRegion(const F32 x, const F32 y) const { // x and y should be region-local coordinates. // If x and y are outside of the surface, then the returned // index will be for the nearest boundary patch. // // 12 | 13| 14| 15 // | | | // +---+---+---+---+ // | 12| 13| 14| 15| // ----+---+---+---+---+----- // 8 | 8 | 9 | 10| 11| 11 // ----+---+---+---+---+----- // 4 | 4 | 5 | 6 | 7 | 7 // ----+---+---+---+---+----- // | 0 | 1 | 2 | 3 | // +---+---+---+---+ // | | | // 0 | 1 | 2 | 3 // // When x and y are not region-local do the following first S32 i, j; if (x < 0.0f) { i = 0; } else if (x >= mMetersPerEdge) { i = mPatchesPerEdge - 1; } else { i = (U32) (x / (mMetersPerGrid * mGridsPerPatchEdge)); } if (y < 0.0f) { j = 0; } else if (y >= mMetersPerEdge) { j = mPatchesPerEdge - 1; } else { j = (U32) (y / (mMetersPerGrid * mGridsPerPatchEdge)); } // *NOTE: Super paranoia code follows. S32 index = i + j * mPatchesPerEdge; if((index < 0) || (index >= mNumberOfPatches)) { if(0 == mNumberOfPatches) { llwarns << "No patches for current region!" << llendl; return NULL; } S32 old_index = index; index = llclamp(old_index, 0, (mNumberOfPatches - 1)); llwarns << "Clamping out of range patch index " << old_index << " to " << index << llendl; } return &(mPatchList[index]); }
BOOL LLNetMap::handleScrollWheel(S32 x, S32 y, S32 clicks) { // note that clicks are reversed from what you'd think setScale(llclamp(mScale - clicks*MAP_SCALE_INCREMENT, MAP_SCALE_MIN, MAP_SCALE_MAX)); return TRUE; }