//-----------------------------------------------------------------------------
// zoom()
//-----------------------------------------------------------------------------
void LLImagePreviewAvatar::zoom(F32 zoom_amt)
{
	mCameraZoom	= llclamp(mCameraZoom + zoom_amt, 1.f, 10.f);
}
Beispiel #2
0
void LLImageTGA::decodeColorMapPixel15( U8* dst, const U8* src )
{
	S32 index = llclamp( *src - mColorMapStart, 0, mColorMapLength - 1 );
	decodeTruecolorPixel15( dst, mColorMap + 2 * index );
}
Beispiel #3
0
//-----------------------------------------------------------------------------
// 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);
}
Beispiel #7
0
// 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;
}
Beispiel #8
0
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;
    }
}
Beispiel #10
0
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);
}
Beispiel #19
0
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));
}
Beispiel #20
0
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);
}
Beispiel #22
0
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);
}
Beispiel #24
0
// 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;
}
Beispiel #25
0
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);
}
Beispiel #27
0
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);
}
Beispiel #29
0
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]);
}
Beispiel #30
0
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;
}