PageRenderTime 152ms CodeModel.GetById 52ms app.highlight 94ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llglsandbox.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 880 lines | 586 code | 153 blank | 141 comment | 96 complexity | 091ed1abc0eb1f3b6396391b02715075 MD5 | raw file
  1/** 
  2 * @file llglsandbox.cpp
  3 * @brief GL functionality access
  4 *
  5 * $LicenseInfo:firstyear=2003&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27/** 
 28 * Contains ALL methods which directly access GL functionality 
 29 * except for core rendering engine functionality.
 30 */
 31
 32#include "llviewerprecompiledheaders.h"
 33
 34#include "llviewercontrol.h"
 35
 36#include "llgl.h"
 37#include "llrender.h"
 38#include "llglheaders.h"
 39#include "llparcel.h"
 40#include "llui.h"
 41
 42#include "lldrawable.h"
 43#include "lltextureentry.h"
 44#include "llviewercamera.h"
 45
 46#include "llvoavatarself.h"
 47#include "llagent.h"
 48#include "lltoolmgr.h"
 49#include "llselectmgr.h"
 50#include "llhudmanager.h"
 51#include "llhudtext.h"
 52#include "llrendersphere.h"
 53#include "llviewerobjectlist.h"
 54#include "lltoolselectrect.h"
 55#include "llviewerwindow.h"
 56#include "llsurface.h"
 57#include "llwind.h"
 58#include "llworld.h"
 59#include "llviewerparcelmgr.h"
 60#include "llviewerregion.h"
 61#include "llpreviewtexture.h"
 62#include "llresmgr.h"
 63#include "pipeline.h"
 64#include "llspatialpartition.h"
 65
 66// Height of the yellow selection highlight posts for land
 67const F32 PARCEL_POST_HEIGHT = 0.666f;
 68
 69// Returns true if you got at least one object
 70void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask)
 71{
 72	LLVector3 av_pos = gAgent.getPositionAgent();
 73	F32 select_dist_squared = gSavedSettings.getF32("MaxSelectDistance");
 74	select_dist_squared = select_dist_squared * select_dist_squared;
 75
 76	BOOL deselect = (mask == MASK_CONTROL);
 77	S32 left =	llmin(x, mDragStartX);
 78	S32 right =	llmax(x, mDragStartX);
 79	S32 top =	llmax(y, mDragStartY);
 80	S32 bottom =llmin(y, mDragStartY);
 81
 82	left = llround((F32) left * LLUI::sGLScaleFactor.mV[VX]);
 83	right = llround((F32) right * LLUI::sGLScaleFactor.mV[VX]);
 84	top = llround((F32) top * LLUI::sGLScaleFactor.mV[VY]);
 85	bottom = llround((F32) bottom * LLUI::sGLScaleFactor.mV[VY]);
 86
 87	F32 old_far_plane = LLViewerCamera::getInstance()->getFar();
 88	F32 old_near_plane = LLViewerCamera::getInstance()->getNear();
 89
 90	S32 width = right - left + 1;
 91	S32 height = top - bottom + 1;
 92
 93	BOOL grow_selection = FALSE;
 94	BOOL shrink_selection = FALSE;
 95
 96	if (height > mDragLastHeight || width > mDragLastWidth)
 97	{
 98		grow_selection = TRUE;
 99	}
100	if (height < mDragLastHeight || width < mDragLastWidth)
101	{
102		shrink_selection = TRUE;
103	}
104
105	if (!grow_selection && !shrink_selection)
106	{
107		// nothing to do
108		return;
109	}
110
111	mDragLastHeight = height;
112	mDragLastWidth = width;
113
114	S32 center_x = (left + right) / 2;
115	S32 center_y = (top + bottom) / 2;
116
117	// save drawing mode
118	gGL.matrixMode(LLRender::MM_PROJECTION);
119	gGL.pushMatrix();
120
121	BOOL limit_select_distance = gSavedSettings.getBOOL("LimitSelectDistance");
122	if (limit_select_distance)
123	{
124		// ...select distance from control
125		LLVector3 relative_av_pos = av_pos;
126		relative_av_pos -= LLViewerCamera::getInstance()->getOrigin();
127
128		F32 new_far = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() + gSavedSettings.getF32("MaxSelectDistance");
129		F32 new_near = relative_av_pos * LLViewerCamera::getInstance()->getAtAxis() - gSavedSettings.getF32("MaxSelectDistance");
130
131		new_near = llmax(new_near, 0.1f);
132
133		LLViewerCamera::getInstance()->setFar(new_far);
134		LLViewerCamera::getInstance()->setNear(new_near);
135	}
136	LLViewerCamera::getInstance()->setPerspective(FOR_SELECTION, 
137							center_x-width/2, center_y-height/2, width, height, 
138							limit_select_distance);
139
140	if (shrink_selection)
141	{
142		struct f : public LLSelectedObjectFunctor
143		{
144			virtual bool apply(LLViewerObject* vobjp)
145			{
146				LLDrawable* drawable = vobjp->mDrawable;
147				if (!drawable || vobjp->getPCode() != LL_PCODE_VOLUME || vobjp->isAttachment())
148				{
149					return true;
150				}
151				S32 result = LLViewerCamera::getInstance()->sphereInFrustum(drawable->getPositionAgent(), drawable->getRadius());
152				switch (result)
153				{
154				  case 0:
155					LLSelectMgr::getInstance()->unhighlightObjectOnly(vobjp);
156					break;
157				  case 1:
158					// check vertices
159					if (!LLViewerCamera::getInstance()->areVertsVisible(vobjp, LLSelectMgr::sRectSelectInclusive))
160					{
161						LLSelectMgr::getInstance()->unhighlightObjectOnly(vobjp);
162					}
163					break;
164				  default:
165					break;
166				}
167				return true;
168			}
169		} func;
170		LLSelectMgr::getInstance()->getHighlightedObjects()->applyToObjects(&func);
171	}
172
173	if (grow_selection)
174	{
175		std::vector<LLDrawable*> potentials;
176				
177		for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 
178			iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
179		{
180			LLViewerRegion* region = *iter;
181			for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
182			{
183				LLSpatialPartition* part = region->getSpatialPartition(i);
184				if (part)
185				{	
186					part->cull(*LLViewerCamera::getInstance(), &potentials, TRUE);
187				}
188			}
189		}
190		
191		for (std::vector<LLDrawable*>::iterator iter = potentials.begin();
192			 iter != potentials.end(); iter++)
193		{
194			LLDrawable* drawable = *iter;
195			LLViewerObject* vobjp = drawable->getVObj();
196
197			if (!drawable || !vobjp ||
198				vobjp->getPCode() != LL_PCODE_VOLUME || 
199				vobjp->isAttachment() ||
200				(deselect && !vobjp->isSelected()))
201			{
202				continue;
203			}
204
205			if (limit_select_distance && dist_vec_squared(drawable->getWorldPosition(), av_pos) > select_dist_squared)
206			{
207				continue;
208			}
209
210			S32 result = LLViewerCamera::getInstance()->sphereInFrustum(drawable->getPositionAgent(), drawable->getRadius());
211			if (result)
212			{
213				switch (result)
214				{
215				case 1:
216					// check vertices
217					if (LLViewerCamera::getInstance()->areVertsVisible(vobjp, LLSelectMgr::sRectSelectInclusive))
218					{
219						LLSelectMgr::getInstance()->highlightObjectOnly(vobjp);
220					}
221					break;
222				case 2:
223					LLSelectMgr::getInstance()->highlightObjectOnly(vobjp);
224					break;
225				default:
226					break;
227				}
228			}
229		}
230	}
231
232	// restore drawing mode
233	gGL.matrixMode(LLRender::MM_PROJECTION);
234	gGL.popMatrix();
235	gGL.matrixMode(LLRender::MM_MODELVIEW);
236
237	// restore camera
238	LLViewerCamera::getInstance()->setFar(old_far_plane);
239	LLViewerCamera::getInstance()->setNear(old_near_plane);
240	gViewerWindow->setup3DRender();
241}
242
243const F32 WIND_RELATIVE_ALTITUDE			= 25.f;
244
245void LLWind::renderVectors()
246{
247	// Renders the wind as vectors (used for debug)
248	S32 i,j;
249	F32 x,y;
250
251	F32 region_width_meters = LLWorld::getInstance()->getRegionWidthInMeters();
252
253	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
254	gGL.pushMatrix();
255	LLVector3 origin_agent;
256	origin_agent = gAgent.getPosAgentFromGlobal(mOriginGlobal);
257	gGL.translatef(origin_agent.mV[VX], origin_agent.mV[VY], gAgent.getPositionAgent().mV[VZ] + WIND_RELATIVE_ALTITUDE);
258	for (j = 0; j < mSize; j++)
259	{
260		for (i = 0; i < mSize; i++)
261		{
262			x = mVelX[i + j*mSize] * WIND_SCALE_HACK;
263			y = mVelY[i + j*mSize] * WIND_SCALE_HACK;
264			gGL.pushMatrix();
265			gGL.translatef((F32)i * region_width_meters/mSize, (F32)j * region_width_meters/mSize, 0.0);
266			gGL.color3f(0,1,0);
267			gGL.begin(LLRender::POINTS);
268				gGL.vertex3f(0,0,0);
269			gGL.end();
270			gGL.color3f(1,0,0);
271			gGL.begin(LLRender::LINES);
272				gGL.vertex3f(x * 0.1f, y * 0.1f ,0.f);
273				gGL.vertex3f(x, y, 0.f);
274			gGL.end();
275			gGL.popMatrix();
276		}
277	}
278	gGL.popMatrix();
279}
280
281
282
283
284// Used by lltoolselectland
285void LLViewerParcelMgr::renderRect(const LLVector3d &west_south_bottom_global, 
286								   const LLVector3d &east_north_top_global )
287{
288	LLGLSUIDefault gls_ui;
289	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
290	LLGLDepthTest gls_depth(GL_TRUE);
291
292	LLVector3 west_south_bottom_agent = gAgent.getPosAgentFromGlobal(west_south_bottom_global);
293	F32 west	= west_south_bottom_agent.mV[VX];
294	F32 south	= west_south_bottom_agent.mV[VY];
295//	F32 bottom	= west_south_bottom_agent.mV[VZ] - 1.f;
296
297	LLVector3 east_north_top_agent = gAgent.getPosAgentFromGlobal(east_north_top_global);
298	F32 east	= east_north_top_agent.mV[VX];
299	F32 north	= east_north_top_agent.mV[VY];
300//	F32 top		= east_north_top_agent.mV[VZ] + 1.f;
301
302	// HACK: At edge of last region of world, we need to make sure the region
303	// resolves correctly so we can get a height value.
304	const F32 FUDGE = 0.01f;
305
306	F32 sw_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( west, south, 0.f ) );
307	F32 se_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( east-FUDGE, south, 0.f ) );
308	F32 ne_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( east-FUDGE, north-FUDGE, 0.f ) );
309	F32 nw_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( west, north-FUDGE, 0.f ) );
310
311	F32 sw_top = sw_bottom + PARCEL_POST_HEIGHT;
312	F32 se_top = se_bottom + PARCEL_POST_HEIGHT;
313	F32 ne_top = ne_bottom + PARCEL_POST_HEIGHT;
314	F32 nw_top = nw_bottom + PARCEL_POST_HEIGHT;
315
316	LLUI::setLineWidth(2.f);
317	gGL.color4f(1.f, 1.f, 0.f, 1.f);
318
319	// Cheat and give this the same pick-name as land
320	gGL.begin(LLRender::LINES);
321
322	gGL.vertex3f(west, north, nw_bottom);
323	gGL.vertex3f(west, north, nw_top);
324
325	gGL.vertex3f(east, north, ne_bottom);
326	gGL.vertex3f(east, north, ne_top);
327
328	gGL.vertex3f(east, south, se_bottom);
329	gGL.vertex3f(east, south, se_top);
330
331	gGL.vertex3f(west, south, sw_bottom);
332	gGL.vertex3f(west, south, sw_top);
333
334	gGL.end();
335
336	gGL.color4f(1.f, 1.f, 0.f, 0.2f);
337	gGL.begin(LLRender::QUADS);
338
339	gGL.vertex3f(west, north, nw_bottom);
340	gGL.vertex3f(west, north, nw_top);
341	gGL.vertex3f(east, north, ne_top);
342	gGL.vertex3f(east, north, ne_bottom);
343
344	gGL.vertex3f(east, north, ne_bottom);
345	gGL.vertex3f(east, north, ne_top);
346	gGL.vertex3f(east, south, se_top);
347	gGL.vertex3f(east, south, se_bottom);
348
349	gGL.vertex3f(east, south, se_bottom);
350	gGL.vertex3f(east, south, se_top);
351	gGL.vertex3f(west, south, sw_top);
352	gGL.vertex3f(west, south, sw_bottom);
353
354	gGL.vertex3f(west, south, sw_bottom);
355	gGL.vertex3f(west, south, sw_top);
356	gGL.vertex3f(west, north, nw_top);
357	gGL.vertex3f(west, north, nw_bottom);
358
359	gGL.end();
360
361	LLUI::setLineWidth(1.f);
362}
363
364/*
365void LLViewerParcelMgr::renderParcel(LLParcel* parcel )
366{
367	S32 i;
368	S32 count = parcel->getBoxCount();
369	for (i = 0; i < count; i++)
370	{
371		const LLParcelBox& box = parcel->getBox(i);
372
373		F32 west = box.mMin.mV[VX];
374		F32 south = box.mMin.mV[VY];
375
376		F32 east = box.mMax.mV[VX];
377		F32 north = box.mMax.mV[VY];
378
379		// HACK: At edge of last region of world, we need to make sure the region
380		// resolves correctly so we can get a height value.
381		const F32 FUDGE = 0.01f;
382
383		F32 sw_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( west, south, 0.f ) );
384		F32 se_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( east-FUDGE, south, 0.f ) );
385		F32 ne_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( east-FUDGE, north-FUDGE, 0.f ) );
386		F32 nw_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( west, north-FUDGE, 0.f ) );
387
388		// little hack to make nearby lines not Z-fight
389		east -= 0.1f;
390		north -= 0.1f;
391
392		F32 sw_top = sw_bottom + POST_HEIGHT;
393		F32 se_top = se_bottom + POST_HEIGHT;
394		F32 ne_top = ne_bottom + POST_HEIGHT;
395		F32 nw_top = nw_bottom + POST_HEIGHT;
396
397		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
398		LLGLDepthTest gls_depth(GL_TRUE);
399
400		LLUI::setLineWidth(2.f);
401		gGL.color4f(0.f, 1.f, 1.f, 1.f);
402
403		// Cheat and give this the same pick-name as land
404		gGL.begin(LLRender::LINES);
405
406		gGL.vertex3f(west, north, nw_bottom);
407		gGL.vertex3f(west, north, nw_top);
408
409		gGL.vertex3f(east, north, ne_bottom);
410		gGL.vertex3f(east, north, ne_top);
411
412		gGL.vertex3f(east, south, se_bottom);
413		gGL.vertex3f(east, south, se_top);
414
415		gGL.vertex3f(west, south, sw_bottom);
416		gGL.vertex3f(west, south, sw_top);
417
418		gGL.end();
419
420		gGL.color4f(0.f, 1.f, 1.f, 0.2f);
421		gGL.begin(LLRender::QUADS);
422
423		gGL.vertex3f(west, north, nw_bottom);
424		gGL.vertex3f(west, north, nw_top);
425		gGL.vertex3f(east, north, ne_top);
426		gGL.vertex3f(east, north, ne_bottom);
427
428		gGL.vertex3f(east, north, ne_bottom);
429		gGL.vertex3f(east, north, ne_top);
430		gGL.vertex3f(east, south, se_top);
431		gGL.vertex3f(east, south, se_bottom);
432
433		gGL.vertex3f(east, south, se_bottom);
434		gGL.vertex3f(east, south, se_top);
435		gGL.vertex3f(west, south, sw_top);
436		gGL.vertex3f(west, south, sw_bottom);
437
438		gGL.vertex3f(west, south, sw_bottom);
439		gGL.vertex3f(west, south, sw_top);
440		gGL.vertex3f(west, north, nw_top);
441		gGL.vertex3f(west, north, nw_bottom);
442
443		gGL.end();
444
445		LLUI::setLineWidth(1.f);
446	}
447}
448*/
449
450
451// north = a wall going north/south.  Need that info to set up texture
452// coordinates correctly.
453void LLViewerParcelMgr::renderOneSegment(F32 x1, F32 y1, F32 x2, F32 y2, F32 height, U8 direction, LLViewerRegion* regionp)
454{
455	// HACK: At edge of last region of world, we need to make sure the region
456	// resolves correctly so we can get a height value.
457	const F32 BORDER = REGION_WIDTH_METERS - 0.1f;
458
459	F32 clamped_x1 = x1;
460	F32 clamped_y1 = y1;
461	F32 clamped_x2 = x2;
462	F32 clamped_y2 = y2;
463
464	if (clamped_x1 > BORDER) clamped_x1 = BORDER;
465	if (clamped_y1 > BORDER) clamped_y1 = BORDER;
466	if (clamped_x2 > BORDER) clamped_x2 = BORDER;
467	if (clamped_y2 > BORDER) clamped_y2 = BORDER;
468
469	F32 z;
470	F32 z1;
471	F32 z2;
472
473	z1 = regionp->getLand().resolveHeightRegion( LLVector3( clamped_x1, clamped_y1, 0.f ) );
474	z2 = regionp->getLand().resolveHeightRegion( LLVector3( clamped_x2, clamped_y2, 0.f ) );
475
476	// Convert x1 and x2 from region-local to agent coords.
477	LLVector3 origin = regionp->getOriginAgent();
478	x1 += origin.mV[VX];
479	x2 += origin.mV[VX];
480	y1 += origin.mV[VY];
481	y2 += origin.mV[VY];
482
483	if (height < 1.f)
484	{
485		z = z1+height;
486		gGL.vertex3f(x1, y1, z);
487
488		gGL.vertex3f(x1, y1, z1);
489
490		gGL.vertex3f(x2, y2, z2);
491
492		z = z2+height;
493		gGL.vertex3f(x2, y2, z);
494	}
495	else
496	{
497		F32 tex_coord1;
498		F32 tex_coord2;
499
500		if (WEST_MASK == direction)
501		{
502			tex_coord1 = y1;
503			tex_coord2 = y2;
504		}
505		else if (SOUTH_MASK == direction)
506		{
507			tex_coord1 = x1;
508			tex_coord2 = x2;
509		}
510		else if (EAST_MASK == direction)
511		{
512			tex_coord1 = y2;
513			tex_coord2 = y1;
514		}
515		else /* (NORTH_MASK == direction) */
516		{
517			tex_coord1 = x2;
518			tex_coord2 = x1;
519		}
520
521
522		gGL.texCoord2f(tex_coord1*0.5f+0.5f, z1*0.5f);
523		gGL.vertex3f(x1, y1, z1);
524
525		gGL.texCoord2f(tex_coord2*0.5f+0.5f, z2*0.5f);
526		gGL.vertex3f(x2, y2, z2);
527
528		// top edge stairsteps
529		z = llmax(z2+height, z1+height);
530		gGL.texCoord2f(tex_coord2*0.5f+0.5f, z*0.5f);
531		gGL.vertex3f(x2, y2, z);
532
533		gGL.texCoord2f(tex_coord1*0.5f+0.5f, z*0.5f);
534		gGL.vertex3f(x1, y1, z);
535	}
536}
537
538
539void LLViewerParcelMgr::renderHighlightSegments(const U8* segments, LLViewerRegion* regionp)
540{
541	S32 x, y;
542	F32 x1, y1;	// start point
543	F32 x2, y2;	// end point
544	bool has_segments = false;
545
546	LLGLSUIDefault gls_ui;
547	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
548	LLGLDepthTest gls_depth(GL_TRUE);
549
550	gGL.color4f(1.f, 1.f, 0.f, 0.2f);
551
552	const S32 STRIDE = (mParcelsPerEdge+1);
553
554	// Cheat and give this the same pick-name as land
555	
556	
557	for (y = 0; y < STRIDE; y++)
558	{
559		for (x = 0; x < STRIDE; x++)
560		{
561			U8 segment_mask = segments[x + y*STRIDE];
562
563			if (segment_mask & SOUTH_MASK)
564			{
565				x1 = x * PARCEL_GRID_STEP_METERS;
566				y1 = y * PARCEL_GRID_STEP_METERS;
567
568				x2 = x1 + PARCEL_GRID_STEP_METERS;
569				y2 = y1;
570				
571				if (!has_segments)
572				{
573					has_segments = true;
574					gGL.begin(LLRender::QUADS);
575				}
576				renderOneSegment(x1, y1, x2, y2, PARCEL_POST_HEIGHT, SOUTH_MASK, regionp);
577			}
578
579			if (segment_mask & WEST_MASK)
580			{
581				x1 = x * PARCEL_GRID_STEP_METERS;
582				y1 = y * PARCEL_GRID_STEP_METERS;
583
584				x2 = x1;
585				y2 = y1 + PARCEL_GRID_STEP_METERS;
586
587				if (!has_segments)
588				{
589					has_segments = true;
590					gGL.begin(LLRender::QUADS);
591				}
592				renderOneSegment(x1, y1, x2, y2, PARCEL_POST_HEIGHT, WEST_MASK, regionp);
593			}
594		}
595	}
596
597	if (has_segments)
598	{
599		gGL.end();
600	}
601}
602
603
604void LLViewerParcelMgr::renderCollisionSegments(U8* segments, BOOL use_pass, LLViewerRegion* regionp)
605{
606
607	S32 x, y;
608	F32 x1, y1;	// start point
609	F32 x2, y2;	// end point
610	F32 alpha = 0;
611	F32 dist = 0;
612	F32 dx, dy;
613	F32 collision_height;
614
615	const S32 STRIDE = (mParcelsPerEdge+1);
616	
617	LLVector3 pos = gAgent.getPositionAgent();
618
619	F32 pos_x = pos.mV[VX];
620	F32 pos_y = pos.mV[VY];
621
622	LLGLSUIDefault gls_ui;
623	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
624	LLGLDisable cull(GL_CULL_FACE);
625	
626	if (mCollisionBanned == BA_BANNED)
627	{
628		collision_height = BAN_HEIGHT;
629	}
630	else
631	{
632		collision_height = PARCEL_HEIGHT;
633	}
634
635	
636	if (use_pass && (mCollisionBanned == BA_NOT_ON_LIST))
637	{
638		gGL.getTexUnit(0)->bind(mPassImage);
639	}
640	else
641	{
642		gGL.getTexUnit(0)->bind(mBlockedImage);
643	}
644
645	gGL.begin(LLRender::QUADS);
646
647	for (y = 0; y < STRIDE; y++)
648	{
649		for (x = 0; x < STRIDE; x++)
650		{
651			U8 segment_mask = segments[x + y*STRIDE];
652			U8 direction;
653			const F32 MAX_ALPHA = 0.95f;
654			const S32 DIST_OFFSET = 5;
655			const S32 MIN_DIST_SQ = DIST_OFFSET*DIST_OFFSET;
656			const S32 MAX_DIST_SQ = 169;
657
658			if (segment_mask & SOUTH_MASK)
659			{
660				x1 = x * PARCEL_GRID_STEP_METERS;
661				y1 = y * PARCEL_GRID_STEP_METERS;
662
663				x2 = x1 + PARCEL_GRID_STEP_METERS;
664				y2 = y1;
665
666				dy = (pos_y - y1) + DIST_OFFSET;
667					
668				if (pos_x < x1)
669					dx = pos_x - x1;
670				else if (pos_x > x2)
671					dx = pos_x - x2;
672				else 
673					dx = 0;
674				
675				dist = dx*dx+dy*dy;
676				
677				if (dist < MIN_DIST_SQ)
678					alpha = MAX_ALPHA;
679				else if (dist > MAX_DIST_SQ)
680					alpha = 0.0f;
681				else
682					alpha = 30/dist;
683				
684				alpha = llclamp(alpha, 0.0f, MAX_ALPHA);
685				
686				gGL.color4f(1.f, 1.f, 1.f, alpha);
687
688				if ((pos_y - y1) < 0) direction = SOUTH_MASK;
689				else 		direction = NORTH_MASK;
690
691				// avoid Z fighting
692				renderOneSegment(x1+0.1f, y1+0.1f, x2+0.1f, y2+0.1f, collision_height, direction, regionp);
693
694			}
695
696			if (segment_mask & WEST_MASK)
697			{
698				x1 = x * PARCEL_GRID_STEP_METERS;
699				y1 = y * PARCEL_GRID_STEP_METERS;
700
701				x2 = x1;
702				y2 = y1 + PARCEL_GRID_STEP_METERS;
703
704				dx = (pos_x - x1) + DIST_OFFSET;
705				
706				if (pos_y < y1) 
707					dy = pos_y - y1;
708				else if (pos_y > y2)
709					dy = pos_y - y2;
710				else 
711					dy = 0;
712				
713				dist = dx*dx+dy*dy;
714				
715				if (dist < MIN_DIST_SQ) 
716					alpha = MAX_ALPHA;
717				else if (dist > MAX_DIST_SQ)
718					alpha = 0.0f;
719				else
720					alpha = 30/dist;
721				
722				alpha = llclamp(alpha, 0.0f, MAX_ALPHA);
723
724				gGL.color4f(1.f, 1.f, 1.f, alpha);
725
726				if ((pos_x - x1) > 0) direction = WEST_MASK;
727				else 		direction = EAST_MASK;
728				
729				// avoid Z fighting
730				renderOneSegment(x1+0.1f, y1+0.1f, x2+0.1f, y2+0.1f, collision_height, direction, regionp);
731
732			}
733		}
734	}
735
736	gGL.end();
737}
738
739void draw_line_cube(F32 width, const LLVector3& center)
740{
741	width = 0.5f * width;
742	gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] + width);
743	gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] + width);
744	gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] + width);
745	gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] + width);
746	gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] + width);
747	gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] + width);
748	gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] + width);
749	gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] + width);
750
751	gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] - width);
752	gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] - width);
753	gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] - width);
754	gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] - width);
755	gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] - width);
756	gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] - width);
757	gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] - width);
758	gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] - width);
759
760	gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] + width);
761	gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] - width);
762	gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] + width);
763	gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] - width);
764	gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] + width);
765	gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] - width);
766	gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] + width);
767	gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] - width);
768}
769
770
771void LLViewerObjectList::renderObjectBeacons()
772{
773	if (mDebugBeacons.empty())
774	{
775		return;
776	}
777
778	LLGLSUIDefault gls_ui;
779
780	if (LLGLSLShader::sNoFixedFunction)
781	{
782		gUIProgram.bind();
783	}
784
785	{
786		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
787
788		S32 last_line_width = -1;
789		// gGL.begin(LLRender::LINES); // Always happens in (line_width != last_line_width)
790		
791		for (std::vector<LLDebugBeacon>::iterator iter = mDebugBeacons.begin(); iter != mDebugBeacons.end(); ++iter)
792		{
793			const LLDebugBeacon &debug_beacon = *iter;
794			LLColor4 color = debug_beacon.mColor;
795			color.mV[3] *= 0.25f;
796			S32 line_width = debug_beacon.mLineWidth;
797			if (line_width != last_line_width)
798			{
799				gGL.flush();
800				glLineWidth( (F32)line_width );
801				last_line_width = line_width;
802			}
803
804			const LLVector3 &thisline = debug_beacon.mPositionAgent;
805		
806			gGL.begin(LLRender::LINES);
807			gGL.color4fv(color.mV);
808			gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] - 50.f);
809			gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] + 50.f);
810			gGL.vertex3f(thisline.mV[VX] - 2.f,thisline.mV[VY],thisline.mV[VZ]);
811			gGL.vertex3f(thisline.mV[VX] + 2.f,thisline.mV[VY],thisline.mV[VZ]);
812			gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] - 2.f,thisline.mV[VZ]);
813			gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] + 2.f,thisline.mV[VZ]);
814
815			draw_line_cube(0.10f, thisline);
816			
817			gGL.end();
818		}
819	}
820
821	{
822		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
823		LLGLDepthTest gls_depth(GL_TRUE);
824		
825		S32 last_line_width = -1;
826		// gGL.begin(LLRender::LINES); // Always happens in (line_width != last_line_width)
827		
828		for (std::vector<LLDebugBeacon>::iterator iter = mDebugBeacons.begin(); iter != mDebugBeacons.end(); ++iter)
829		{
830			const LLDebugBeacon &debug_beacon = *iter;
831
832			S32 line_width = debug_beacon.mLineWidth;
833			if (line_width != last_line_width)
834			{
835				gGL.flush();
836				glLineWidth( (F32)line_width );
837				last_line_width = line_width;
838			}
839
840			const LLVector3 &thisline = debug_beacon.mPositionAgent;
841			gGL.begin(LLRender::LINES);
842			gGL.color4fv(debug_beacon.mColor.mV);
843			gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] - 0.5f);
844			gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] + 0.5f);
845			gGL.vertex3f(thisline.mV[VX] - 0.5f,thisline.mV[VY],thisline.mV[VZ]);
846			gGL.vertex3f(thisline.mV[VX] + 0.5f,thisline.mV[VY],thisline.mV[VZ]);
847			gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] - 0.5f,thisline.mV[VZ]);
848			gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] + 0.5f,thisline.mV[VZ]);
849
850			draw_line_cube(0.10f, thisline);
851
852			gGL.end();
853		}
854		
855		gGL.flush();
856		glLineWidth(1.f);
857
858		for (std::vector<LLDebugBeacon>::iterator iter = mDebugBeacons.begin(); iter != mDebugBeacons.end(); ++iter)
859		{
860			LLDebugBeacon &debug_beacon = *iter;
861			if (debug_beacon.mString == "")
862			{
863				continue;
864			}
865			LLHUDText *hud_textp = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT);
866
867			hud_textp->setZCompare(FALSE);
868			LLColor4 color;
869			color = debug_beacon.mTextColor;
870			color.mV[3] *= 1.f;
871
872			hud_textp->setString(debug_beacon.mString);
873			hud_textp->setColor(color);
874			hud_textp->setPositionAgent(debug_beacon.mPositionAgent);
875			debug_beacon.mHUDObject = hud_textp;
876		}
877	}
878}
879
880