Пример #1
0
/*
 * Draw vertical lines from each vertex straight up in world space
 * with lengths indicating the current "strength" slider.
 * Decorate the tops and bottoms of the lines like this:
 *
 *		Raise        Revert
 *		/|\           ___
 *		 |             |
 *		 |             |
 *
 *		Rough        Smooth
 *		/|\           ___
 *		 |             |
 *		 |             |
 *		\|/..........._|_
 *
 *		Lower        Flatten
 *		 |             |
 *		 |             |
 *		\|/..........._|_
 */
void LLToolBrushLand::renderOverlay(LLSurface& land, const LLVector3& pos_region,
									const LLVector3& pos_world)
{
	glMatrixMode(GL_MODELVIEW);
	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
	LLGLDepthTest mDepthTest(GL_TRUE);
	glPushMatrix();
	gGL.color4fv(OVERLAY_COLOR.mV);
	glTranslatef(0.0f, 0.0f, 1.0f);
	
	S32 i = (S32) pos_region.mV[VX];
	S32 j = (S32) pos_region.mV[VY];
	S32 half_edge = llfloor(mBrushSize);
	S32 radioAction = gSavedSettings.getS32("RadioLandBrushAction");
	F32 force = gSavedSettings.getF32("LandBrushForce"); // .1 to 100?
	
	gGL.begin(LLRender::LINES);
	for(S32 di = -half_edge; di <= half_edge; di++)
	{
		if((i+di) < 0 || (i+di) >= (S32)land.mGridsPerEdge) continue;
		for(S32 dj = -half_edge; dj <= half_edge; dj++)
		{
			if( (j+dj) < 0 || (j+dj) >= (S32)land.mGridsPerEdge ) continue;
			const F32 
				wx = pos_world.mV[VX] + di,
				wy = pos_world.mV[VY] + dj,
				wz = land.getZ((i+di)+(j+dj)*land.mGridsPerEdge),
				norm_dist = sqrt((float)di*di + dj*dj) / half_edge,
				force_scale = sqrt(2.f) - norm_dist, // 1 at center, 0 at corner
				wz2 = wz + .2 + (.2 + force/100) * force_scale, // top vertex
				tic = .075f; // arrowhead size
			// vertical line
			gGL.vertex3f(wx, wy, wz);
			gGL.vertex3f(wx, wy, wz2);
			if(radioAction == E_LAND_RAISE || radioAction == E_LAND_NOISE) // up arrow
			{
				gGL.vertex3f(wx, wy, wz2);
				gGL.vertex3f(wx+tic, wy, wz2-tic);
				gGL.vertex3f(wx, wy, wz2);
				gGL.vertex3f(wx-tic, wy, wz2-tic);
			}
			if(radioAction == E_LAND_LOWER || radioAction == E_LAND_NOISE) // down arrow
			{
				gGL.vertex3f(wx, wy, wz);
				gGL.vertex3f(wx+tic, wy, wz+tic);
				gGL.vertex3f(wx, wy, wz);
				gGL.vertex3f(wx-tic, wy, wz+tic);
			}
			if(radioAction == E_LAND_REVERT || radioAction == E_LAND_SMOOTH) // flat top
			{
				gGL.vertex3f(wx-tic, wy, wz2);
				gGL.vertex3f(wx+tic, wy, wz2);
			}
			if(radioAction == E_LAND_LEVEL || radioAction == E_LAND_SMOOTH) // flat bottom
			{
				gGL.vertex3f(wx-tic, wy, wz);
				gGL.vertex3f(wx+tic, wy, wz);
			}
		}
	}
	gGL.end();

	glPopMatrix();
}
S32 LLViewerParcelOverlay::renderPropertyLines	()
{
    if (!gSavedSettings.getBOOL("ShowPropertyLines"))
    {
        return 0;
    }
    if (!mVertexArray || !mColorArray)
    {
        return 0;
    }

    LLSurface& land = mRegion->getLand();

    LLGLSUIDefault gls_ui; // called from pipeline
    gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
    LLGLDepthTest mDepthTest(GL_TRUE, GL_FALSE);

    // Find camera height off the ground (not from zero)
    F32 ground_height_at_camera = land.resolveHeightGlobal( gAgentCamera.getCameraPositionGlobal() );
    F32 camera_z = LLViewerCamera::getInstance()->getOrigin().mV[VZ];
    F32 camera_height = camera_z - ground_height_at_camera;

    camera_height = llclamp(camera_height, 0.f, 100.f);

    // Pull lines toward camera by 1 cm per meter off the ground.
    const LLVector3& CAMERA_AT = LLViewerCamera::getInstance()->getAtAxis();
    F32 pull_toward_camera_scale = 0.01f * camera_height;
    LLVector3 pull_toward_camera = CAMERA_AT;
    pull_toward_camera *= -pull_toward_camera_scale;

    // Always fudge a little vertically.
    pull_toward_camera.mV[VZ] += 0.01f;

    gGL.matrixMode(LLRender::MM_MODELVIEW);
    gGL.pushMatrix();

    // Move to appropriate region coords
    LLVector3 origin = mRegion->getOriginAgent();
    gGL.translatef( origin.mV[VX], origin.mV[VY], origin.mV[VZ] );

    gGL.translatef(pull_toward_camera.mV[VX], pull_toward_camera.mV[VY],
                   pull_toward_camera.mV[VZ]);

    // Include +1 because vertices are fenceposts.
    // *2 because it's a quad strip
    const S32 GRID_STEP = S32( PARCEL_GRID_STEP_METERS );
    const S32 vertex_per_edge = 3 + 2 * (GRID_STEP-1) + 3;

    // Stomp the camera into two dimensions
    LLVector3 camera_region = mRegion->getPosRegionFromGlobal( gAgentCamera.getCameraPositionGlobal() );

    // Set up a cull plane 2 * PARCEL_GRID_STEP_METERS behind
    // the camera.  The cull plane normal is the camera's at axis.
    LLVector3 cull_plane_point = LLViewerCamera::getInstance()->getAtAxis();
    cull_plane_point *= -2.f * PARCEL_GRID_STEP_METERS;
    cull_plane_point += camera_region;

    LLVector3 vertex;

    const S32 BYTES_PER_COLOR = 4;
    const S32 FLOATS_PER_VERTEX = 3;
    //const S32 FLOATS_PER_TEX_COORD = 2;
    S32 i, j;
    S32 drawn = 0;
    F32* vertexp;
    U8* colorp;

    const F32 PROPERTY_LINE_CLIP_DIST_SQUARED = 256.f * 256.f;

    for (i = 0; i < mVertexCount; i += vertex_per_edge)
    {
        colorp  = mColorArray  + BYTES_PER_COLOR   * i;
        vertexp = mVertexArray + FLOATS_PER_VERTEX * i;

        vertex.mV[VX] = *(vertexp);
        vertex.mV[VY] = *(vertexp+1);
        vertex.mV[VZ] = *(vertexp+2);

        if (dist_vec_squared2D(vertex, camera_region) > PROPERTY_LINE_CLIP_DIST_SQUARED)
        {
            continue;
        }

        // Destroy vertex, transform to plane-local.
        vertex -= cull_plane_point;

        // negative dot product means it is in back of the plane
        if ( vertex * CAMERA_AT < 0.f )
        {
            continue;
        }

        gGL.begin(LLRender::TRIANGLE_STRIP);

        for (j = 0; j < vertex_per_edge; j++)
        {
            gGL.color4ubv(colorp);
            gGL.vertex3fv(vertexp);

            colorp  += BYTES_PER_COLOR;
            vertexp += FLOATS_PER_VERTEX;
        }

        drawn += vertex_per_edge;

        gGL.end();

        if (LLSelectMgr::sRenderHiddenSelections && gFloaterTools && gFloaterTools->getVisible())
        {
            LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER);

            colorp  = mColorArray  + BYTES_PER_COLOR   * i;
            vertexp = mVertexArray + FLOATS_PER_VERTEX * i;

            gGL.begin(LLRender::TRIANGLE_STRIP);

            for (j = 0; j < vertex_per_edge; j++)
            {
                U8 color[4];
                color[0] = colorp[0];
                color[1] = colorp[1];
                color[2] = colorp[2];
                color[3] = colorp[3]/4;

                gGL.color4ubv(color);
                gGL.vertex3fv(vertexp);

                colorp  += BYTES_PER_COLOR;
                vertexp += FLOATS_PER_VERTEX;
            }

            drawn += vertex_per_edge;

            gGL.end();
        }

    }

    gGL.popMatrix();

    return drawn;
}