Beispiel #1
0
S32	LLGlobalEconomy::calculateLightRent(const LLVector3& object_size) const
{
	F32 intensity_mod = llmax(object_size.magVec(), 1.f);
	return (S32)(intensity_mod * getPriceRentLight());
}
void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude)
{
	LLVector3 wind_pos;
	F64 pitch;
	F64 center_freq;
	ALenum error;
	
	if (!mEnableWind)
		return;
	
	if (!mWindBuf)
		return;
	
	if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL))
	{
		
		// wind comes in as Linden coordinate (+X = forward, +Y = left, +Z = up)
		// need to convert this to the conventional orientation DS3D and OpenAL use
		// where +X = right, +Y = up, +Z = backwards
		
		wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]);
		
		pitch = 1.0 + mapWindVecToPitch(wind_vec);
		center_freq = 80.0 * pow(pitch,2.5*(mapWindVecToGain(wind_vec)+1.0));
		
		mWindGen->mTargetFreq = (F32)center_freq;
		mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain;
		mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec);
		
		alSourcei(mWindSource, AL_LOOPING, AL_FALSE);
		alSource3f(mWindSource, AL_POSITION, 0.0, 0.0, 0.0);
		alSource3f(mWindSource, AL_VELOCITY, 0.0, 0.0, 0.0);
		alSourcef(mWindSource, AL_ROLLOFF_FACTOR, 0.0);
		alSourcei(mWindSource, AL_SOURCE_RELATIVE, AL_TRUE);
	}

	// ok lets make a wind buffer now

	ALint processed, queued, unprocessed;
	alGetSourcei(mWindSource, AL_BUFFERS_PROCESSED, &processed);
	alGetSourcei(mWindSource, AL_BUFFERS_QUEUED, &queued);
	unprocessed = queued - processed;

	// ensure that there are always at least 3x as many filled buffers
	// queued as we managed to empty since last time.
	mNumEmptyWindALBuffers = llmin(mNumEmptyWindALBuffers + processed * 3 - unprocessed, MAX_NUM_WIND_BUFFERS-unprocessed);
	mNumEmptyWindALBuffers = llmax(mNumEmptyWindALBuffers, 0);

	//llinfos << "mNumEmptyWindALBuffers: " << mNumEmptyWindALBuffers	<<" (" << unprocessed << ":" << processed << ")" << llendl;

	while (processed--) // unqueue old buffers
	{
		ALuint buffer;
		ALenum error;
		alGetError(); /* clear error */
		alSourceUnqueueBuffers(mWindSource, 1, &buffer);
		error = alGetError();
		if (error != AL_NO_ERROR)
		{
			llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (unqueuing) buffers" << llendl;
		}
		else
		{
			alDeleteBuffers(1, &buffer);
		}
	}

	unprocessed += mNumEmptyWindALBuffers;
	while (mNumEmptyWindALBuffers > 0) // fill+queue new buffers
	{
		ALuint buffer;
		alGetError(); /* clear error */
		alGenBuffers(1,&buffer);
		if ((error=alGetError()) != AL_NO_ERROR)
		{
			llwarns << "LLAudioEngine_OpenAL::updateWind() Error creating wind buffer: " << convertALErrorToString(error) << llendl;
			break;
		}

		alBufferData(buffer,
			     AL_FORMAT_STEREO16,
			     mWindGen->windGenerate(mWindBuf,
						    mWindBufSamples),
			     mWindBufBytes,
			     mWindBufFreq);
		error = alGetError();
		if (error != AL_NO_ERROR)
		{
			llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (bufferdata) buffers" << llendl;
		}
		
		alSourceQueueBuffers(mWindSource, 1, &buffer);
		error = alGetError();
		if (error != AL_NO_ERROR)
		{
			llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (queuing) buffers" << llendl;
		}

		--mNumEmptyWindALBuffers;
	}

	ALint playing;
	alGetSourcei(mWindSource, AL_SOURCE_STATE, &playing);
	if (playing != AL_PLAYING)
	{
		alSourcePlay(mWindSource);

		lldebugs << "Wind had stopped - probably ran out of buffers - restarting: " 
				<< (unprocessed+mNumEmptyWindALBuffers) << " now queued." 
				<< llendl;
	}
}
// writes contents to datapacker
BOOL LLBVHLoader::serialize(LLDataPacker& dp)
{
	JointVector::iterator ji;
	KeyVector::iterator ki;
	F32 time;

	// count number of non-ignored joints
	S32 numJoints = 0;
	for (ji=mJoints.begin(); ji!=mJoints.end(); ++ji)
	{
		Joint *joint = *ji;
		if ( ! joint->mIgnore )
			numJoints++;
	}

	// print header
	dp.packU16(KEYFRAME_MOTION_VERSION, "version");
	dp.packU16(KEYFRAME_MOTION_SUBVERSION, "sub_version");
	dp.packS32(mPriority, "base_priority");
	dp.packF32(mDuration, "duration");
	dp.packString(mEmoteName, "emote_name");
	dp.packF32(mLoopInPoint, "loop_in_point");
	dp.packF32(mLoopOutPoint, "loop_out_point");
	dp.packS32(mLoop, "loop");
	dp.packF32(mEaseIn, "ease_in_duration");
	dp.packF32(mEaseOut, "ease_out_duration");
	dp.packU32(mHand, "hand_pose");
	dp.packU32(numJoints, "num_joints");

	for (	ji = mJoints.begin();
			ji != mJoints.end();
			++ji )
	{
		Joint *joint = *ji;
		// if ignored, skip it
		if ( joint->mIgnore )
			continue;

		LLQuaternion first_frame_rot;
		LLQuaternion fixup_rot;

		dp.packString(joint->mOutName, "joint_name");
		dp.packS32(joint->mPriority, "joint_priority");

		// compute coordinate frame rotation
		LLQuaternion frameRot( joint->mFrameMatrix );
		LLQuaternion frameRotInv = ~frameRot;

		LLQuaternion offsetRot( joint->mOffsetMatrix );

		// find mergechild and mergeparent joints, if specified
		LLQuaternion mergeParentRot;
		LLQuaternion mergeChildRot;
		Joint *mergeParent = NULL;
		Joint *mergeChild = NULL;

		JointVector::iterator mji;
		for (mji=mJoints.begin(); mji!=mJoints.end(); ++mji)
		{
			Joint *mjoint = *mji;
			if ( !joint->mMergeParentName.empty() && (mjoint->mName == joint->mMergeParentName) )
			{
				mergeParent = *mji;
			}
			if ( !joint->mMergeChildName.empty() && (mjoint->mName == joint->mMergeChildName) )
			{
				mergeChild = *mji;
			}
		}

		dp.packS32(joint->mNumRotKeys, "num_rot_keys");

		LLQuaternion::Order order = bvhStringToOrder( joint->mOrder );
		S32 outcount = 0;
		S32 frame = 1;
		for (	ki = joint->mKeys.begin();
				ki != joint->mKeys.end();
				++ki )
		{
			if ((frame == 1) && joint->mRelativeRotationKey)
			{
				first_frame_rot = mayaQ( ki->mRot[0], ki->mRot[1], ki->mRot[2], order);
				
				fixup_rot.shortestArc(LLVector3::z_axis * first_frame_rot * frameRot, LLVector3::z_axis);
			}

			if (ki->mIgnoreRot)
			{
				frame++;
				continue;
			}

			time = (F32)frame * mFrameTime;

			if (mergeParent)
			{
				mergeParentRot = mayaQ(	mergeParent->mKeys[frame-1].mRot[0], 
										mergeParent->mKeys[frame-1].mRot[1],
										mergeParent->mKeys[frame-1].mRot[2],
										bvhStringToOrder(mergeParent->mOrder) );
				LLQuaternion parentFrameRot( mergeParent->mFrameMatrix );
				LLQuaternion parentOffsetRot( mergeParent->mOffsetMatrix );
				mergeParentRot = ~parentFrameRot * mergeParentRot * parentFrameRot * parentOffsetRot;
			}
			else
			{
				mergeParentRot.loadIdentity();
			}

			if (mergeChild)
			{
				mergeChildRot = mayaQ(	mergeChild->mKeys[frame-1].mRot[0], 
										mergeChild->mKeys[frame-1].mRot[1],
										mergeChild->mKeys[frame-1].mRot[2],
										bvhStringToOrder(mergeChild->mOrder) );
				LLQuaternion childFrameRot( mergeChild->mFrameMatrix );
				LLQuaternion childOffsetRot( mergeChild->mOffsetMatrix );
				mergeChildRot = ~childFrameRot * mergeChildRot * childFrameRot * childOffsetRot;
				
			}
			else
			{
				mergeChildRot.loadIdentity();
			}

			LLQuaternion inRot = mayaQ( ki->mRot[0], ki->mRot[1], ki->mRot[2], order);

			LLQuaternion outRot =  frameRotInv* mergeChildRot * inRot * mergeParentRot * ~first_frame_rot * frameRot * offsetRot;

			U16 time_short = F32_to_U16(time, 0.f, mDuration);
			dp.packU16(time_short, "time");
			U16 x, y, z;
			LLVector3 rot_vec = outRot.packToVector3();
			rot_vec.quantize16(-1.f, 1.f, -1.f, 1.f);
			x = F32_to_U16(rot_vec.mV[VX], -1.f, 1.f);
			y = F32_to_U16(rot_vec.mV[VY], -1.f, 1.f);
			z = F32_to_U16(rot_vec.mV[VZ], -1.f, 1.f);
			dp.packU16(x, "rot_angle_x");
			dp.packU16(y, "rot_angle_y");
			dp.packU16(z, "rot_angle_z");
			outcount++;
			frame++;
		}
		
		// output position keys (only for 1st joint)
		if ( ji == mJoints.begin() && !joint->mIgnorePositions )
		{
			dp.packS32(joint->mNumPosKeys, "num_pos_keys");

			LLVector3 relPos = joint->mRelativePosition;
			LLVector3 relKey;

			frame = 1;
			for (	ki = joint->mKeys.begin();
					ki != joint->mKeys.end();
					++ki )
			{
				if ((frame == 1) && joint->mRelativePositionKey)
				{
					relKey.setVec(ki->mPos);
				}

				if (ki->mIgnorePos)
				{
					frame++;
					continue;
				}

				time = (F32)frame * mFrameTime;

				LLVector3 inPos = (LLVector3(ki->mPos) - relKey) * ~first_frame_rot;// * fixup_rot;
				LLVector3 outPos = inPos * frameRot * offsetRot;

				outPos *= INCHES_TO_METERS;

				outPos -= relPos;
				outPos.clamp(-LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);

				U16 time_short = F32_to_U16(time, 0.f, mDuration);
				dp.packU16(time_short, "time");

				U16 x, y, z;
				outPos.quantize16(-LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
				x = F32_to_U16(outPos.mV[VX], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
				y = F32_to_U16(outPos.mV[VY], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
				z = F32_to_U16(outPos.mV[VZ], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
				dp.packU16(x, "pos_x");
				dp.packU16(y, "pos_y");
				dp.packU16(z, "pos_z");

				frame++;
			}
		}
		else
		{
			dp.packS32(0, "num_pos_keys");
		}
	}

	S32 num_constraints = (S32)mConstraints.size();
	dp.packS32(num_constraints, "num_constraints");

	for (ConstraintVector::iterator constraint_it = mConstraints.begin();
		constraint_it != mConstraints.end();
		constraint_it++)
		{
			U8 byte = constraint_it->mChainLength;
			dp.packU8(byte, "chain_length");
			
			byte = constraint_it->mConstraintType;
			dp.packU8(byte, "constraint_type");
			dp.packBinaryDataFixed((U8*)constraint_it->mSourceJointName, 16, "source_volume");
			dp.packVector3(constraint_it->mSourceOffset, "source_offset");
			dp.packBinaryDataFixed((U8*)constraint_it->mTargetJointName, 16, "target_volume");
			dp.packVector3(constraint_it->mTargetOffset, "target_offset");
			dp.packVector3(constraint_it->mTargetDir, "target_dir");
			dp.packF32(constraint_it->mEaseInStart,	"ease_in_start");
			dp.packF32(constraint_it->mEaseInStop,	"ease_in_stop");
			dp.packF32(constraint_it->mEaseOutStart,	"ease_out_start");
			dp.packF32(constraint_it->mEaseOutStop,	"ease_out_stop");
		}

	return TRUE;
}
Beispiel #4
0
// -----------------------------------------------------------------------------
void LLViewerJoystick::moveFlycam(bool reset)
{
	static LLQuaternion 		sFlycamRotation;
	static LLVector3    		sFlycamPosition;
	static F32          		sFlycamZoom;
	
	if (!gFocusMgr.getAppHasFocus() || mDriverState != JDS_INITIALIZED
		|| !gSavedSettings.getBOOL("JoystickEnabled") || !gSavedSettings.getBOOL("JoystickFlycamEnabled"))
	{
		return;
	}

	S32 axis[] = 
	{
		gSavedSettings.getS32("JoystickAxis0"),
		gSavedSettings.getS32("JoystickAxis1"),
		gSavedSettings.getS32("JoystickAxis2"),
		gSavedSettings.getS32("JoystickAxis3"),
		gSavedSettings.getS32("JoystickAxis4"),
		gSavedSettings.getS32("JoystickAxis5"),
		gSavedSettings.getS32("JoystickAxis6")
	};

	bool in_build_mode = LLToolMgr::getInstance()->inBuildMode();
	if (reset || mResetFlag)
	{
		sFlycamPosition = LLViewerCamera::getInstance()->getOrigin();
		sFlycamRotation = LLViewerCamera::getInstance()->getQuaternion();
		sFlycamZoom = LLViewerCamera::getInstance()->getView();
		
		resetDeltas(axis);

		return;
	}

	F32 axis_scale[] =
	{
		gSavedSettings.getF32("FlycamAxisScale0"),
		gSavedSettings.getF32("FlycamAxisScale1"),
		gSavedSettings.getF32("FlycamAxisScale2"),
		gSavedSettings.getF32("FlycamAxisScale3"),
		gSavedSettings.getF32("FlycamAxisScale4"),
		gSavedSettings.getF32("FlycamAxisScale5"),
		gSavedSettings.getF32("FlycamAxisScale6")
	};

	F32 dead_zone[] =
	{
		gSavedSettings.getF32("FlycamAxisDeadZone0"),
		gSavedSettings.getF32("FlycamAxisDeadZone1"),
		gSavedSettings.getF32("FlycamAxisDeadZone2"),
		gSavedSettings.getF32("FlycamAxisDeadZone3"),
		gSavedSettings.getF32("FlycamAxisDeadZone4"),
		gSavedSettings.getF32("FlycamAxisDeadZone5"),
		gSavedSettings.getF32("FlycamAxisDeadZone6")
	};

	F32 time = gFrameIntervalSeconds;

	// avoid making ridicously big movements if there's a big drop in fps 
	if (time > .2f)
	{
		time = .2f;
	}

	F32 cur_delta[7];
	F32 feather = gSavedSettings.getF32("FlycamFeathering");
	bool absolute = gSavedSettings.getBOOL("Cursor3D");

	for (U32 i = 0; i < 7; i++)
	{
		cur_delta[i] = -getJoystickAxis(axis[i]);


		F32 tmp = cur_delta[i];
		if (absolute)
		{
			cur_delta[i] = cur_delta[i] - sLastDelta[i];
		}
		sLastDelta[i] = tmp;

		if (cur_delta[i] > 0)
		{
			cur_delta[i] = llmax(cur_delta[i]-dead_zone[i], 0.f);
		}
		else
		{
			cur_delta[i] = llmin(cur_delta[i]+dead_zone[i], 0.f);
		}

		// we need smaller camera movements in build mode
		// NOTE: this needs to remain after the deadzone calculation, otherwise
		// we have issues with flycam "jumping" when the build dialog is opened/closed  -Nyx
		if (in_build_mode)
		{
			if (i == X_I || i == Y_I || i == Z_I)
			{
				cur_delta[i] /= BUILDMODE_FLYCAM_T_SCALE;
			}
		}

		cur_delta[i] *= axis_scale[i];
		
		if (!absolute)
		{
			cur_delta[i] *= time;
		}

		sDelta[i] = sDelta[i] + (cur_delta[i]-sDelta[i])*time*feather;
	}
	
	sFlycamPosition += LLVector3(sDelta) * sFlycamRotation;

	LLMatrix3 rot_mat(sDelta[3], sDelta[4], sDelta[5]);
	sFlycamRotation = LLQuaternion(rot_mat)*sFlycamRotation;

	if (gSavedSettings.getBOOL("AutoLeveling"))
	{
		LLMatrix3 level(sFlycamRotation);

		LLVector3 x = LLVector3(level.mMatrix[0]);
		LLVector3 y = LLVector3(level.mMatrix[1]);
		LLVector3 z = LLVector3(level.mMatrix[2]);

		y.mV[2] = 0.f;
		y.normVec();

		level.setRows(x,y,z);
		level.orthogonalize();
				
		LLQuaternion quat(level);
		sFlycamRotation = nlerp(llmin(feather*time,1.f), sFlycamRotation, quat);
	}

	if (gSavedSettings.getBOOL("ZoomDirect"))
	{
		sFlycamZoom = sLastDelta[6]*axis_scale[6]+dead_zone[6];
	}
	else
	{
		sFlycamZoom += sDelta[6];
	}

	LLMatrix3 mat(sFlycamRotation);

	LLViewerCamera::getInstance()->setView(sFlycamZoom);
	LLViewerCamera::getInstance()->setOrigin(sFlycamPosition);
	LLViewerCamera::getInstance()->mXAxis = LLVector3(mat.mMatrix[0]);
	LLViewerCamera::getInstance()->mYAxis = LLVector3(mat.mMatrix[1]);
	LLViewerCamera::getInstance()->mZAxis = LLVector3(mat.mMatrix[2]);
}
BOOL LLVOWLSky::updateStarGeometry(LLDrawable *drawable)
{
	LLStrider<LLVector3> verticesp;
	LLStrider<LLColor4U> colorsp;
	LLStrider<LLVector2> texcoordsp;

	if (mStarsVerts.isNull())
	{
		mStarsVerts = new LLVertexBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK, GL_DYNAMIC_DRAW);
		mStarsVerts->allocateBuffer(getStarsNumVerts()*6, 0, TRUE);
	}

	BOOL success = mStarsVerts->getVertexStrider(verticesp)
		&& mStarsVerts->getColorStrider(colorsp)
		&& mStarsVerts->getTexCoord0Strider(texcoordsp);

	if(!success)
	{
		llerrs << "Failed updating star geometry." << llendl;
	}

	// *TODO: fix LLStrider with a real prefix increment operator so it can be
	// used as a model of OutputIterator. -Brad
	// std::copy(mStarVertices.begin(), mStarVertices.end(), verticesp);

	if (mStarVertices.size() < getStarsNumVerts())
	{
		llerrs << "Star reference geometry insufficient." << llendl;
	}

	for (U32 vtx = 0; vtx < getStarsNumVerts(); ++vtx)
	{
		LLVector3 at = mStarVertices[vtx];
		at.normVec();
		LLVector3 left = at%LLVector3(0,0,1);
		LLVector3 up = at%left;

		F32 sc = 0.5f+ll_frand()*1.25f;
		left *= sc;
		up *= sc;

		*(verticesp++)  = mStarVertices[vtx];
		*(verticesp++) = mStarVertices[vtx]+left;
		*(verticesp++) = mStarVertices[vtx]+left+up;
		*(verticesp++) = mStarVertices[vtx]+left;
		*(verticesp++) = mStarVertices[vtx]+left+up;
		*(verticesp++) = mStarVertices[vtx]+up;

		*(texcoordsp++) = LLVector2(0,0);
		*(texcoordsp++) = LLVector2(0,1);
		*(texcoordsp++) = LLVector2(1,1);
		*(texcoordsp++) = LLVector2(0,1);
		*(texcoordsp++) = LLVector2(1,1);
		*(texcoordsp++) = LLVector2(1,0);

		*(colorsp++)    = LLColor4U(mStarColors[vtx]);
		*(colorsp++)    = LLColor4U(mStarColors[vtx]);
		*(colorsp++)    = LLColor4U(mStarColors[vtx]);
		*(colorsp++)    = LLColor4U(mStarColors[vtx]);
		*(colorsp++)    = LLColor4U(mStarColors[vtx]);
		*(colorsp++)    = LLColor4U(mStarColors[vtx]);
	}

	mStarsVerts->flush();
	return TRUE;
}
BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a& intersection, BOOL debug_render)
{
	if (!mVisible || mHidden)
	{
		return FALSE;
	}

	// don't pick text that isn't bound to a viewerobject
	if (!mSourceObject || mSourceObject->mDrawable.isNull())
	{
		return FALSE;
	}
	
	F32 alpha_factor = 1.f;
	LLColor4 text_color = mColor;
	if (mDoFade)
	{
		if (mLastDistance > mFadeDistance)
		{
			alpha_factor = llmax(0.f, 1.f - (mLastDistance - mFadeDistance)/mFadeRange);
			text_color.mV[3] = text_color.mV[3]*alpha_factor;
		}
	}
	if (text_color.mV[3] < 0.01f)
	{
		return FALSE;
	}

	mOffsetY = lltrunc(mHeight * ((mVertAlignment == ALIGN_VERT_CENTER) ? 0.5f : 1.f));

	LLVector3 position = mPositionAgent;

	if (mSourceObject)
	{ //get intersection of eye through mPositionAgent to plane of source object
		//using this position keeps the camera from focusing on some seemingly random 
		//point several meters in front of the nametag
		const LLVector3& p = mSourceObject->getPositionAgent();
		const LLVector3& n = LLViewerCamera::getInstance()->getAtAxis();
		const LLVector3& eye = LLViewerCamera::getInstance()->getOrigin();

		LLVector3 ray = position-eye;
		ray.normalize();

		LLVector3 delta = p-position;
		F32 dist = delta*n;
		F32 dt =  dist/(ray*n);
		position += ray*dt;
	}

	// scale screen size of borders down

	LLVector3 x_pixel_vec;
	LLVector3 y_pixel_vec;
	
	LLViewerCamera::getInstance()->getPixelVectors(position, y_pixel_vec, x_pixel_vec);

	LLVector3 width_vec = mWidth * x_pixel_vec;
	LLVector3 height_vec = mHeight * y_pixel_vec;
	
	LLCoordGL screen_pos;
	LLViewerCamera::getInstance()->projectPosAgentToScreen(position, screen_pos, FALSE);

	LLVector2 screen_offset;
	screen_offset = updateScreenPos(mPositionOffset);
	
	LLVector3 render_position = position  
			+ (x_pixel_vec * screen_offset.mV[VX])
			+ (y_pixel_vec * screen_offset.mV[VY]);


	LLVector3 bg_pos = render_position
		+ (F32)mOffsetY * y_pixel_vec
		- (width_vec / 2.f)
		- (height_vec);

	LLVector3 v[] = 
	{
		bg_pos,
		bg_pos + width_vec,
		bg_pos + width_vec + height_vec,
		bg_pos + height_vec,
	};

	LLVector4a dir;
	dir.setSub(end,start);
	F32 a, b, t;

	LLVector4a v0,v1,v2,v3;
	v0.load3(v[0].mV);
	v1.load3(v[1].mV);
	v2.load3(v[2].mV);
	v3.load3(v[3].mV);

	if (LLTriangleRayIntersect(v0, v1, v2, start, dir, a, b, t) ||
		LLTriangleRayIntersect(v2, v3, v0, start, dir, a, b, t) )
	{
		if (t <= 1.f)
		{
			dir.mul(t);
			intersection.setAdd(start, dir);
			return TRUE;
		}
	}

	return FALSE;
}
void LLVOPartGroup::getGeometry(S32 idx,
								LLStrider<LLVector3>& verticesp,
								LLStrider<LLVector3>& normalsp, 
								LLStrider<LLVector2>& texcoordsp,
								LLStrider<LLColor4U>& colorsp, 
								LLStrider<U16>& indicesp)
{
	if (idx >= (S32) mViewerPartGroupp->mParticles.size())
	{
		return;
	}

	const LLViewerPart &part = *((LLViewerPart*) (mViewerPartGroupp->mParticles[idx]));

	U32 vert_offset = mDrawable->getFace(idx)->getGeomIndex();

	
	LLVector3 part_pos_agent(part.mPosAgent);
	LLVector3 camera_agent = getCameraPosition(); 
	LLVector3 at = part_pos_agent - camera_agent;
	LLVector3 up;
	LLVector3 right;

	right = at % LLVector3(0.f, 0.f, 1.f);
	right.normalize();
	up = right % at;
	up.normalize();

	if (part.mFlags & LLPartData::LL_PART_FOLLOW_VELOCITY_MASK)
	{
		LLVector3 normvel = part.mVelocity;
		normvel.normalize();
		LLVector2 up_fracs;
		up_fracs.mV[0] = normvel*right;
		up_fracs.mV[1] = normvel*up;
		up_fracs.normalize();
		LLVector3 new_up;
		LLVector3 new_right;
		new_up = up_fracs.mV[0] * right + up_fracs.mV[1]*up;
		new_right = up_fracs.mV[1] * right - up_fracs.mV[0]*up;
		up = new_up;
		right = new_right;
		up.normalize();
		right.normalize();
	}

	right *= 0.5f*part.mScale.mV[0];
	up *= 0.5f*part.mScale.mV[1];


	LLVector3 normal = -LLViewerCamera::getInstance()->getXAxis();
		
	*verticesp++ = part_pos_agent + up - right;
	*verticesp++ = part_pos_agent - up - right;
	*verticesp++ = part_pos_agent + up + right;
	*verticesp++ = part_pos_agent - up + right;

	*colorsp++ = part.mColor;
	*colorsp++ = part.mColor;
	*colorsp++ = part.mColor;
	*colorsp++ = part.mColor;

	*texcoordsp++ = LLVector2(0.f, 1.f);
	*texcoordsp++ = LLVector2(0.f, 0.f);
	*texcoordsp++ = LLVector2(1.f, 1.f);
	*texcoordsp++ = LLVector2(1.f, 0.f);

	*normalsp++   = normal;
	*normalsp++   = normal;
	*normalsp++   = normal;
	*normalsp++   = normal;

	*indicesp++ = vert_offset + 0;
	*indicesp++ = vert_offset + 1;
	*indicesp++ = vert_offset + 2;

	*indicesp++ = vert_offset + 1;
	*indicesp++ = vert_offset + 3;
	*indicesp++ = vert_offset + 2;
}
void LLPanelPrimMediaControls::updateShape()
{
	LLViewerMediaImpl* media_impl = getTargetMediaImpl();
	LLViewerObject* objectp = getTargetObject();
	
	if(!media_impl || gFloaterTools->getVisible())
	{
		setVisible(FALSE);
		return;
	}

	LLPluginClassMedia* media_plugin = NULL;
	if(media_impl->hasMedia())
	{
		media_plugin = media_impl->getMediaPlugin();
	}
	
	LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();

	bool can_navigate = parcel->getMediaAllowNavigate();
	bool enabled = false;
	bool is_zoomed = (mCurrentZoom != ZOOM_NONE) && (mTargetObjectID == mZoomObjectID) && (mTargetObjectFace == mZoomObjectFace);
	// There is no such thing as "has_focus" being different from normal controls set
	// anymore (as of user feedback from bri 10/09).  So we cheat here and force 'has_focus'
	// to 'true' (or, actually, we use a setting)
	bool has_focus = (gSavedSettings.getBOOL("PrimMediaControlsUseHoverControlSet")) ? media_impl->hasFocus() : true;
	setVisible(enabled);

	if (objectp)
	{
		// <FS:ND> VWR-29449; Remeber if user has MEDIA_PERM_CONTROL	
		bool hasPermsControl = true;
		// </FS:ND>

		bool mini_controls = false;
		LLMediaEntry *media_data = objectp->getTE(mTargetObjectFace)->getMediaData();
		if (media_data && NULL != dynamic_cast<LLVOVolume*>(objectp))
		{
			// Don't show the media controls if we do not have permissions
			enabled = dynamic_cast<LLVOVolume*>(objectp)->hasMediaPermission(media_data, LLVOVolume::MEDIA_PERM_CONTROL);
		
			// <FS:ND> VWR-29449; Remeber if user has MEDIA_PERM_CONTROL
			hasPermsControl = dynamic_cast<LLVOVolume*>(objectp)->hasMediaPermission(media_data, LLVOVolume::MEDIA_PERM_CONTROL);
			// </FS:ND>

			mini_controls = (LLMediaEntry::MINI == media_data->getControls());
		}
		const bool is_hud = objectp->isHUDAttachment();
		
		//
		// Set the state of the buttons
		//
		
		// XXX RSP: TODO: FIXME: clean this up so that it is clearer what mode we are in,
		// and that only the proper controls get made visible/enabled according to that mode. 
		mBackCtrl->setVisible(has_focus);
		mFwdCtrl->setVisible(has_focus);
		mReloadCtrl->setVisible(has_focus);
		mStopCtrl->setVisible(false);
		mHomeCtrl->setVisible(has_focus);
		mZoomCtrl->setVisible(!is_zoomed);
		mUnzoomCtrl->setVisible(is_zoomed);
		mOpenCtrl->setVisible(true);
		mMediaAddressCtrl->setVisible(has_focus && !mini_controls);
		mMediaPlaySliderPanel->setVisible(has_focus && !mini_controls);
		mVolumeCtrl->setVisible(false);
		
		mWhitelistIcon->setVisible(!mini_controls && (media_data)?media_data->getWhiteListEnable():false);
		// Disable zoom if HUD
		mZoomCtrl->setEnabled(!is_hud);
		mUnzoomCtrl->setEnabled(!is_hud);
        mSecureURL = false;
		mCurrentURL = media_impl->getCurrentMediaURL();
		
		mBackCtrl->setEnabled((media_impl != NULL) && media_impl->canNavigateBack() && can_navigate);
		mFwdCtrl->setEnabled((media_impl != NULL) && media_impl->canNavigateForward() && can_navigate);
		mStopCtrl->setEnabled(has_focus && can_navigate);
		mHomeCtrl->setEnabled(has_focus && can_navigate);
		LLPluginClassMediaOwner::EMediaStatus result = ((media_impl != NULL) && media_impl->hasMedia()) ? media_plugin->getStatus() : LLPluginClassMediaOwner::MEDIA_NONE;
		
		mVolumeCtrl->setVisible(has_focus);
		mVolumeCtrl->setEnabled(has_focus);
		mVolumeSliderCtrl->setEnabled(has_focus && shouldVolumeSliderBeVisible());
		mVolumeSliderCtrl->setVisible(has_focus && shouldVolumeSliderBeVisible());

		if(media_plugin && media_plugin->pluginSupportsMediaTime())
		{
			mReloadCtrl->setEnabled(false);
			mReloadCtrl->setVisible(false);
			mMediaStopCtrl->setVisible(has_focus);
			mHomeCtrl->setVisible(has_focus);
			mBackCtrl->setVisible(false);
			mFwdCtrl->setVisible(false);
			mMediaAddressCtrl->setVisible(false);
			mMediaAddressCtrl->setEnabled(false);
			mMediaPlaySliderPanel->setVisible(has_focus && !mini_controls);
			mMediaPlaySliderPanel->setEnabled(has_focus && !mini_controls);
			mSkipFwdCtrl->setVisible(has_focus && !mini_controls);
			mSkipFwdCtrl->setEnabled(has_focus && !mini_controls);
			mSkipBackCtrl->setVisible(has_focus && !mini_controls);
			mSkipBackCtrl->setEnabled(has_focus && !mini_controls);
			
			mVolumeCtrl->setVisible(has_focus);
			mVolumeCtrl->setEnabled(has_focus);
			mVolumeSliderCtrl->setEnabled(has_focus && shouldVolumeSliderBeVisible());
			mVolumeSliderCtrl->setVisible(has_focus && shouldVolumeSliderBeVisible());
			
			mWhitelistIcon->setVisible(false);
            mSecureURL = false;
			if (mMediaPanelScroll)
			{
				mMediaPanelScroll->setVisible(false);
				mScrollUpCtrl->setVisible(false);
				mScrollDownCtrl->setVisible(false);
				mScrollRightCtrl->setVisible(false);
				mScrollDownCtrl->setVisible(false);
			}
			
			F32 volume = media_impl->getVolume();
			// movie's url changed
			if(mCurrentURL!=mPreviousURL)
			{
				mMovieDuration = media_plugin->getDuration();
				mPreviousURL = mCurrentURL;
			}
			
			if(mMovieDuration == 0) 
			{
				mMovieDuration = media_plugin->getDuration();
				mMediaPlaySliderCtrl->setValue(0);
				mMediaPlaySliderCtrl->setEnabled(false);
			}
			// TODO: What if it's not fully loaded
			
			if(mUpdateSlider && mMovieDuration!= 0)
			{
				F64 current_time =  media_plugin->getCurrentTime();
				F32 percent = current_time / mMovieDuration;
				mMediaPlaySliderCtrl->setValue(percent);
				mMediaPlaySliderCtrl->setEnabled(true);
			}
			
			// video volume
			if(volume <= 0.0)
			{
				mMuteBtn->setToggleState(true);
			}
			else if (volume >= 1.0)
			{
				mMuteBtn->setToggleState(false);
			}
			else
			{
				mMuteBtn->setToggleState(false);
			}
			
			switch(result)
			{
				case LLPluginClassMediaOwner::MEDIA_PLAYING:
					mPlayCtrl->setEnabled(FALSE);
					mPlayCtrl->setVisible(FALSE);
					mPauseCtrl->setEnabled(TRUE);
					mPauseCtrl->setVisible(has_focus);
					
					break;
				case LLPluginClassMediaOwner::MEDIA_PAUSED:
				default:
					mPauseCtrl->setEnabled(FALSE);
					mPauseCtrl->setVisible(FALSE);
					mPlayCtrl->setEnabled(TRUE);
					mPlayCtrl->setVisible(has_focus);
					break;
			}
		}
		else   // web based
		{
			if(media_plugin)
			{
				mCurrentURL = media_plugin->getLocation();
			}
			else
			{
				mCurrentURL.clear();
			}
			
			mPlayCtrl->setVisible(FALSE);
			mPauseCtrl->setVisible(FALSE);
			mMediaStopCtrl->setVisible(FALSE);
			mMediaAddressCtrl->setVisible(has_focus && !mini_controls);
			mMediaAddressCtrl->setEnabled(has_focus && !mini_controls);
			mMediaPlaySliderPanel->setVisible(FALSE);
			mMediaPlaySliderPanel->setEnabled(FALSE);
			mSkipFwdCtrl->setVisible(FALSE);
			mSkipFwdCtrl->setEnabled(FALSE);
			mSkipBackCtrl->setVisible(FALSE);
			mSkipBackCtrl->setEnabled(FALSE);
			
			if(media_impl->getVolume() <= 0.0)
			{
				mMuteBtn->setToggleState(true);
			}
			else
			{
				mMuteBtn->setToggleState(false);
			}

			if (mMediaPanelScroll)
			{
				mMediaPanelScroll->setVisible(has_focus);
				mScrollUpCtrl->setVisible(has_focus);
				mScrollDownCtrl->setVisible(has_focus);
				mScrollRightCtrl->setVisible(has_focus);
				mScrollDownCtrl->setVisible(has_focus);
			}
			// TODO: get the secure lock bool from media plug in
			std::string prefix =  std::string("https://");
			std::string test_prefix = mCurrentURL.substr(0, prefix.length());
			LLStringUtil::toLower(test_prefix);
            mSecureURL = has_focus && (test_prefix == prefix);
            mCurrentURL = (mSecureURL ? "      " + mCurrentURL : mCurrentURL);
			
			if(mCurrentURL!=mPreviousURL)
			{
				setCurrentURL();
				mPreviousURL = mCurrentURL;
			}
			
			if(result == LLPluginClassMediaOwner::MEDIA_LOADING)
			{
				mReloadCtrl->setEnabled(FALSE);
				mReloadCtrl->setVisible(FALSE);
				mStopCtrl->setEnabled(TRUE);
				mStopCtrl->setVisible(has_focus);
			}
			else
			{
				mReloadCtrl->setEnabled(TRUE);
				mReloadCtrl->setVisible(has_focus);
				mStopCtrl->setEnabled(FALSE);
				mStopCtrl->setVisible(FALSE);
			}
		}
		
		
		if(media_plugin)
		{
			//
			// Handle progress bar
			//
			if(LLPluginClassMediaOwner::MEDIA_LOADING == media_plugin->getStatus())
			{	
				mMediaProgressPanel->setVisible(true);
				mMediaProgressBar->setValue(media_plugin->getProgressPercent());
			}
			else
			{
				mMediaProgressPanel->setVisible(false);
			}
		}
		
		if(media_impl)
		{
			//
			// Handle Scrolling
			//
			switch (mScrollState) 
			{
				case SCROLL_UP:
					media_impl->scrollWheel(0, -1, MASK_NONE);
					break;
				case SCROLL_DOWN:
					media_impl->scrollWheel(0, 1, MASK_NONE);
					break;
				case SCROLL_LEFT:
					media_impl->scrollWheel(1, 0, MASK_NONE);
					//				media_impl->handleKeyHere(KEY_LEFT, MASK_NONE);
					break;
				case SCROLL_RIGHT:
					media_impl->scrollWheel(-1, 0, MASK_NONE);
					//				media_impl->handleKeyHere(KEY_RIGHT, MASK_NONE);
					break;
				case SCROLL_NONE:
				default:
					break;
			}
		}
		
		// <FS:ND> VWR-29449; If this is a HUD always set it visible, but hide each control if user has no perms.
		// When setting it invisible it won't receive any mouse messages anymore, thus eg trying to sroll a webpage with mousewheel has surprising effects.

		// setVisible(enabled);
		if( !is_hud )
			setVisible(enabled);
		else
		{
			if( !hasPermsControl )
			{
				mBackCtrl->setVisible(false);
				mFwdCtrl->setVisible(false);
				mReloadCtrl->setVisible(false);
				mStopCtrl->setVisible(false);
				mHomeCtrl->setVisible(false);
				mZoomCtrl->setVisible(false);
				mUnzoomCtrl->setVisible(false);
				mOpenCtrl->setVisible(false);
				mMediaAddressCtrl->setVisible(false);
				mMediaPlaySliderPanel->setVisible(false);
				mVolumeCtrl->setVisible(false);
				mMediaProgressPanel->setVisible(false);
				mVolumeSliderCtrl->setVisible(false);
			}

			setVisible(true);
		}
		
		// </FS:ND>

		//
		// Calculate position and shape of the controls
		//
		std::vector<LLVector3>::iterator vert_it;
		std::vector<LLVector3>::iterator vert_end;
		std::vector<LLVector3> vect_face;
		
		LLVolume* volume = objectp->getVolume();
		
		if (volume)
		{
			const LLVolumeFace& vf = volume->getVolumeFace(mTargetObjectFace);
			
			LLVector3 ext[2];
			ext[0].set(vf.mExtents[0].getF32ptr());
			ext[1].set(vf.mExtents[1].getF32ptr());
			
			LLVector3 center = (ext[0]+ext[1])*0.5f;
			LLVector3 size = (ext[1]-ext[0])*0.5f;
			LLVector3 vert[] =
			{
				center + size.scaledVec(LLVector3(1,1,1)),
				center + size.scaledVec(LLVector3(-1,1,1)),
				center + size.scaledVec(LLVector3(1,-1,1)),
				center + size.scaledVec(LLVector3(-1,-1,1)),
				center + size.scaledVec(LLVector3(1,1,-1)),
				center + size.scaledVec(LLVector3(-1,1,-1)),
				center + size.scaledVec(LLVector3(1,-1,-1)),
				center + size.scaledVec(LLVector3(-1,-1,-1)),
			};
			
			LLVOVolume* vo = (LLVOVolume*) objectp;
			
			for (U32 i = 0; i < 8; i++)
			{
				vect_face.push_back(vo->volumePositionToAgent(vert[i]));
			}
		}
		vert_it = vect_face.begin();
		vert_end = vect_face.end();
		
		glh::matrix4f mat;
		if (!is_hud) 
		{
			mat = glh_get_current_projection() * glh_get_current_modelview();
		}
		else {
			glh::matrix4f proj, modelview;
			if (get_hud_matrices(proj, modelview))
				mat = proj * modelview;
		}
		LLVector3 min = LLVector3(1,1,1);
		LLVector3 max = LLVector3(-1,-1,-1);
		for(; vert_it != vert_end; ++vert_it)
		{
			// project silhouette vertices into screen space
			glh::vec3f screen_vert = glh::vec3f(vert_it->mV); 
			mat.mult_matrix_vec(screen_vert);
			
			// add to screenspace bounding box
			update_min_max(min, max, LLVector3(screen_vert.v));
		}
		
		// convert screenspace bbox to pixels (in screen coords)
		LLRect window_rect = gViewerWindow->getWorldViewRectScaled();
		LLCoordGL screen_min;
		screen_min.mX = llround((F32)window_rect.mLeft + (F32)window_rect.getWidth() * (min.mV[VX] + 1.f) * 0.5f);
		screen_min.mY = llround((F32)window_rect.mBottom + (F32)window_rect.getHeight() * (min.mV[VY] + 1.f) * 0.5f);
		
		LLCoordGL screen_max;
		screen_max.mX = llround((F32)window_rect.mLeft + (F32)window_rect.getWidth() * (max.mV[VX] + 1.f) * 0.5f);
		screen_max.mY = llround((F32)window_rect.mBottom + (F32)window_rect.getHeight() * (max.mV[VY] + 1.f) * 0.5f);
		
		// grow panel so that screenspace bounding box fits inside "media_region" element of panel
		LLRect media_panel_rect;
		// Get the height of the controls (less the volume slider)
		S32 controls_height = mMediaControlsStack->getRect().getHeight() - mVolumeSliderCtrl->getRect().getHeight();
		getParent()->screenRectToLocal(LLRect(screen_min.mX, screen_max.mY, screen_max.mX, screen_min.mY), &media_panel_rect);
		media_panel_rect.mTop += controls_height;
		
		// keep all parts of panel on-screen
		// Area of the top of the world view to avoid putting the controls
		window_rect.mTop -= mTopWorldViewAvoidZone;
		// Don't include "spacing" bookends on left & right of the media controls
		window_rect.mLeft -= mLeftBookend->getRect().getWidth();
		window_rect.mRight += mRightBookend->getRect().getWidth();
		// Don't include the volume slider
		window_rect.mBottom -= mVolumeSliderCtrl->getRect().getHeight();
		media_panel_rect.intersectWith(window_rect);
		
		// clamp to minimum size, keeping rect inside window
		S32 centerX = media_panel_rect.getCenterX();
		S32 centerY = media_panel_rect.getCenterY();
		// Shrink screen rect by min width and height, to ensure containment
		window_rect.stretch(-mMinWidth/2, -mMinHeight/2);
		window_rect.clampPointToRect(centerX, centerY);
		media_panel_rect.setCenterAndSize(centerX, centerY, 
										  llmax(mMinWidth, media_panel_rect.getWidth()),
										  llmax(mMinHeight, media_panel_rect.getHeight()));
		
		// Finally set the size of the panel
		setShape(media_panel_rect, true);
		
		// Test mouse position to see if the cursor is stationary
		LLCoordWindow cursor_pos_window;
		getWindow()->getCursorPosition(&cursor_pos_window);
		
		// If last pos is not equal to current pos, the mouse has moved
		// We need to reset the timer, and make sure the panel is visible
		if(cursor_pos_window.mX != mLastCursorPos.mX ||
		   cursor_pos_window.mY != mLastCursorPos.mY ||
		   mScrollState != SCROLL_NONE)
		{
			mInactivityTimer.start();
			mLastCursorPos = cursor_pos_window;
		}
		
		if(isMouseOver() || hasFocus())
		{
			// Never fade the controls if the mouse is over them or they have keyboard focus.
			mFadeTimer.stop();
		}
		else if(!mClearFaceOnFade && (mInactivityTimer.getElapsedTimeF32() < mInactiveTimeout))
		{
			// Mouse is over the object, but has not been stationary for long enough to fade the UI
			mFadeTimer.stop();
		}
		else if(! mFadeTimer.getStarted() )
		{
			// we need to start fading the UI (and we have not already started)
			mFadeTimer.reset();
			mFadeTimer.start();
		}
		else
		{
			// I don't think this is correct anymore.  This is done in draw() after the fade has completed.
			//			setVisible(FALSE);
		}
	}
}
//-----------------------------------------------------------------------------
// postBuild()
//-----------------------------------------------------------------------------
BOOL LLFloaterAnimPreview::postBuild()
{
	LLRect r;
	LLKeyframeMotion* motionp = NULL;
	LLBVHLoader* loaderp = NULL;

	if (!LLFloaterNameDesc::postBuild())
	{
		return FALSE;
	}

	mInWorld = gSavedSettings.getBOOL("PreviewAnimInWorld");

	childSetCommitCallback("name_form", onCommitName, this);

	if (gSavedSettings.getBOOL("AscentPowerfulWizard"))
	{
		childSetMaxValue("priority", 7);
	}

	childSetLabelArg("ok_btn", "[UPLOADFEE]", gHippoGridManager->getConnectedGrid()->getUploadFee());
	childSetAction("ok_btn", onBtnOK, this);
	setDefaultBtn();

	if (mInWorld)
	{
		r = getRect();
		translate(0, 230);
		reshape(r.getWidth(), r.getHeight() - 230);
		childSetValue("bad_animation_text", getString("in_world"));
		childShow("bad_animation_text");
	}
	else
	{
		childHide("bad_animation_text");
	}

	mPreviewRect.set(PREVIEW_HPAD, 
		PREVIEW_TEXTURE_HEIGHT,
		getRect().getWidth() - PREVIEW_HPAD, 
		PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
	mPreviewImageRect.set(0.f, 1.f, 1.f, 0.f);

	S32 y = mPreviewRect.mTop + BTN_HEIGHT;
	S32 btn_left = PREVIEW_HPAD;

	r.set( btn_left, y, btn_left + 32, y - BTN_HEIGHT );
	mPlayButton = getChild<LLButton>( "play_btn");
	if (!mPlayButton)
	{
		mPlayButton = new LLButton(std::string("play_btn"), LLRect(0,0,0,0));
	}
	mPlayButton->setClickedCallback(onBtnPlay);
	mPlayButton->setCallbackUserData(this);

	mPlayButton->setImages(std::string("button_anim_play.tga"),
						   std::string("button_anim_play_selected.tga"));
	mPlayButton->setDisabledImages(LLStringUtil::null,LLStringUtil::null);

	mPlayButton->setScaleImage(TRUE);

	mStopButton = getChild<LLButton>( "stop_btn");
	if (!mStopButton)
	{
		mStopButton = new LLButton(std::string("stop_btn"), LLRect(0,0,0,0));
	}
	mStopButton->setClickedCallback(onBtnStop);
	mStopButton->setCallbackUserData(this);

	mStopButton->setImages(std::string("button_anim_stop.tga"),
						   std::string("button_anim_stop_selected.tga"));
	mStopButton->setDisabledImages(LLStringUtil::null,LLStringUtil::null);

	mStopButton->setScaleImage(TRUE);

	r.set(r.mRight + PREVIEW_HPAD, y, getRect().getWidth() - PREVIEW_HPAD, y - BTN_HEIGHT);
	//childSetCommitCallback("playback_slider", onSliderMove, this);

	//childSetCommitCallback("preview_base_anim", onCommitBaseAnim, this);
	//childSetValue("preview_base_anim", "Standing");

	//childSetCommitCallback("priority", onCommitPriority, this);
	//childSetCommitCallback("loop_check", onCommitLoop, this);
	//childSetCommitCallback("loop_in_point", onCommitLoopIn, this);
	//childSetValidate("loop_in_point", validateLoopIn);
	//childSetCommitCallback("loop_out_point", onCommitLoopOut, this);
	//childSetValidate("loop_out_point", validateLoopOut);

	//childSetCommitCallback("hand_pose_combo", onCommitHandPose, this);
	
	//childSetCommitCallback("emote_combo", onCommitEmote, this);
	//childSetValue("emote_combo", "[None]");

	//childSetCommitCallback("ease_in_time", onCommitEaseIn, this);
	//childSetValidate("ease_in_time", validateEaseIn);
	//childSetCommitCallback("ease_out_time", onCommitEaseOut, this);
	//childSetValidate("ease_out_time", validateEaseOut);

	// <edit> moved declaration from below
	BOOL success = false;
	// </edit>

	std::string exten = gDirUtilp->getExtension(mFilename);
	if (exten == "bvh")
	{
		// loading a bvh file

		// now load bvh file
		S32 file_size;
		
		LLAPRFile infile ;
		infile.open(mFilenameAndPath, LL_APR_RB, LLAPRFile::global, &file_size);
		
		if (!infile.getFileHandle())
		{
			llwarns << "Can't open BVH file:" << mFilename << llendl;	
		}
		else
		{
			char*	file_buffer;

			file_buffer = new char[file_size + 1];

			if (file_size == infile.read(file_buffer, file_size))
			{
				file_buffer[file_size] = '\0';
				llinfos << "Loading BVH file " << mFilename << llendl;
				ELoadStatus load_status = E_ST_OK;
				S32 line_number = 0; 
				loaderp = new LLBVHLoader(file_buffer, load_status, line_number);
				std::string status = getString(STATUS[load_status]);
				
				if(load_status == E_ST_NO_XLT_FILE)
				{
					llwarns << "NOTE: No translation table found." << llendl;
				}
				else
				{
					llwarns << "ERROR: [line: " << line_number << "] " << status << llendl;
				}
			}

			infile.close() ;
			delete[] file_buffer;

			// <edit> moved everything bvh from below
			if(loaderp && loaderp->isInitialized() && loaderp->getDuration() <= MAX_ANIM_DURATION)
	{
		mTransactionID.generate();
		mMotionID = mTransactionID.makeAssetID(gAgent.getSecureSessionID());

		mAnimPreview = new LLPreviewAnimation(256, 256);

		// motion will be returned, but it will be in a load-pending state, as this is a new motion
		// this motion will not request an asset transfer until next update, so we have a chance to 
		// load the keyframe data locally
		if (mInWorld)
		{
			motionp = (LLKeyframeMotion*)gAgent.getAvatarObject()->createMotion(mMotionID);
		}
		else
		{
			motionp = (LLKeyframeMotion*)mAnimPreview->getDummyAvatar()->createMotion(mMotionID);
		}

		// create data buffer for keyframe initialization
		S32 buffer_size = loaderp->getOutputSize();
		U8* buffer = new U8[buffer_size];

		LLDataPackerBinaryBuffer dp(buffer, buffer_size);

		// pass animation data through memory buffer
		loaderp->serialize(dp);
		dp.reset();
				success = motionp && motionp->deserialize(dp);
			}
			else
			{
				success = false;
				if ( loaderp )
				{
					if (loaderp->getDuration() > MAX_ANIM_DURATION)
					{
						LLUIString out_str = getString("anim_too_long");
						out_str.setArg("[LENGTH]", llformat("%.1f", loaderp->getDuration()));
						out_str.setArg("[MAX_LENGTH]", llformat("%.1f", MAX_ANIM_DURATION));
						getChild<LLUICtrl>("bad_animation_text")->setValue(out_str.getString());
					}
					else
					{
						LLUIString out_str = getString("failed_file_read");
						out_str.setArg("[STATUS]", getString(STATUS[loaderp->getStatus()])); 
						getChild<LLUICtrl>("bad_animation_text")->setValue(out_str.getString());
					}
				}

				//setEnabled(FALSE);
				mMotionID.setNull();
				mAnimPreview = NULL;
			}
			// </edit>
		}
	}
	// <edit>
	else if(exten == "anim" || exten == "animatn" || exten == "neil")
	{
		S32 file_size;
		LLAPRFile raw_animatn;
		raw_animatn.open(mFilenameAndPath, LL_APR_RB, LLAPRFile::global, &file_size);

		if (!raw_animatn.getFileHandle())
		{
			llwarns << "Can't open animatn file:" << mFilename << llendl;	
		}
		else
		{
			char*	file_buffer;

			file_buffer = new char[file_size + 1];

			if (file_size == raw_animatn.read(file_buffer, file_size))
			{
				file_buffer[file_size] = '\0';
				llinfos << "Loading animatn file " << mFilename << llendl;
				mTransactionID.generate();
				mMotionID = mTransactionID.makeAssetID(gAgent.getSecureSessionID());
				mAnimPreview = new LLPreviewAnimation(256, 256);
				motionp = (LLKeyframeMotion*)mAnimPreview->getDummyAvatar()->createMotion(mMotionID);
				LLDataPackerBinaryBuffer dp((U8*)file_buffer, file_size);
				dp.reset();
				success = motionp && motionp->deserialize(dp);
			}

			raw_animatn.close();
			delete[] file_buffer;
		}
	}
	// </edit>

		if (success)
		{
			setAnimCallbacks() ;

			if (!mInWorld)
			{
				const LLBBoxLocal &pelvis_bbox = motionp->getPelvisBBox();

				LLVector3 temp = pelvis_bbox.getCenter();
				// only consider XY?
				//temp.mV[VZ] = 0.f;
				F32 pelvis_offset = temp.magVec();

				temp = pelvis_bbox.getExtent();
				//temp.mV[VZ] = 0.f;
				F32 pelvis_max_displacement = pelvis_offset + (temp.magVec() * 0.5f) + 1.f;

				F32 camera_zoom = LLViewerCamera::getInstance()->getDefaultFOV() / (2.f * atan(pelvis_max_displacement / PREVIEW_CAMERA_DISTANCE));

				mAnimPreview->setZoom(camera_zoom);
			}

			motionp->setName(childGetValue("name_form").asString());
			if (!mInWorld)
			{
				mAnimPreview->getDummyAvatar()->startMotion(mMotionID);
			}
			childSetMinValue("playback_slider", 0.0);
			childSetMaxValue("playback_slider", 1.0);

			childSetValue("loop_check", LLSD(motionp->getLoop()));
			childSetValue("loop_in_point", LLSD(motionp->getLoopIn() / motionp->getDuration() * 100.f));
			childSetValue("loop_out_point", LLSD(motionp->getLoopOut() / motionp->getDuration() * 100.f));
			childSetValue("priority", LLSD((F32)motionp->getPriority()));
			childSetValue("hand_pose_combo", LLHandMotion::getHandPoseName(motionp->getHandPose()));
			childSetValue("ease_in_time", LLSD(motionp->getEaseInDuration()));
			childSetValue("ease_out_time", LLSD(motionp->getEaseOutDuration()));
			setEnabled(TRUE);
			std::string seconds_string;
			seconds_string = llformat(" - %.2f seconds", motionp->getDuration());

			setTitle(mFilename + std::string(seconds_string));
		}
		else
		{
			delete mAnimPreview;
			mAnimPreview = NULL;
			mMotionID.setNull();
			childSetValue("bad_animation_text", getString("failed_to_initialize"));
		}


	refresh();

	delete loaderp;

	return TRUE;
}
Beispiel #10
0
template <> LLSD convert_to_llsd<LLVector3>(const LLVector3& in) 
{ 
	return in.getValue(); 
}
//static
void LLViewerCamera::updateFrustumPlanes(LLCamera& camera, BOOL ortho, BOOL zflip, BOOL no_hacks)
{
	GLint* viewport = (GLint*) gGLViewport;
	GLdouble* model = gGLModelView;
	GLdouble* proj = gGLProjection;
	GLdouble objX,objY,objZ;

	LLVector3 frust[8];

	if (no_hacks)
	{
		gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ);
		frust[0].setVec((F32)objX,(F32)objY,(F32)objZ);
		gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ);
		frust[1].setVec((F32)objX,(F32)objY,(F32)objZ);
		gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ);
		frust[2].setVec((F32)objX,(F32)objY,(F32)objZ);
		gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ);
		frust[3].setVec((F32)objX,(F32)objY,(F32)objZ);

		gluUnProject(viewport[0],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ);
		frust[4].setVec((F32)objX,(F32)objY,(F32)objZ);
		gluUnProject(viewport[0]+viewport[2],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ);
		frust[5].setVec((F32)objX,(F32)objY,(F32)objZ);
		gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ);
		frust[6].setVec((F32)objX,(F32)objY,(F32)objZ);
		gluUnProject(viewport[0],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ);
		frust[7].setVec((F32)objX,(F32)objY,(F32)objZ);
	}
	else if (zflip)
	{
		gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ);
		frust[0].setVec((F32)objX,(F32)objY,(F32)objZ);
		gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ);
		frust[1].setVec((F32)objX,(F32)objY,(F32)objZ);
		gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ);
		frust[2].setVec((F32)objX,(F32)objY,(F32)objZ);
		gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ);
		frust[3].setVec((F32)objX,(F32)objY,(F32)objZ);

		gluUnProject(viewport[0],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ);
		frust[4].setVec((F32)objX,(F32)objY,(F32)objZ);
		gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ);
		frust[5].setVec((F32)objX,(F32)objY,(F32)objZ);
		gluUnProject(viewport[0]+viewport[2],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ);
		frust[6].setVec((F32)objX,(F32)objY,(F32)objZ);
		gluUnProject(viewport[0],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ);
		frust[7].setVec((F32)objX,(F32)objY,(F32)objZ);

		for (U32 i = 0; i < 4; i++)
		{
			frust[i+4] = frust[i+4]-frust[i];
			frust[i+4].normVec();
			frust[i+4] = frust[i] + frust[i+4]*camera.getFar();
		}
	}
	else
	{
		gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ);
		frust[0].setVec((F32)objX,(F32)objY,(F32)objZ);
		gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ);
		frust[1].setVec((F32)objX,(F32)objY,(F32)objZ);
		gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ);
		frust[2].setVec((F32)objX,(F32)objY,(F32)objZ);
		gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ);
		frust[3].setVec((F32)objX,(F32)objY,(F32)objZ);
		
		if (ortho)
		{
			LLVector3 far_shift = camera.getAtAxis()*camera.getFar()*2.f; 
			for (U32 i = 0; i < 4; i++)
			{
				frust[i+4] = frust[i] + far_shift;
			}
		}
		else
		{
			for (U32 i = 0; i < 4; i++)
			{
				LLVector3 vec = frust[i] - camera.getOrigin();
				vec.normVec();
				frust[i+4] = camera.getOrigin() + vec*camera.getFar();
			}
		}
	}

	camera.calcAgentFrustumPlanes(frust);
}
// we've switched controls, so update spinners, etc.
void LLFloaterSettingsDebug::updateControl()
{
    LLSpinCtrl* spinner1 = getChild<LLSpinCtrl>("val_spinner_1");
    LLSpinCtrl* spinner2 = getChild<LLSpinCtrl>("val_spinner_2");
    LLSpinCtrl* spinner3 = getChild<LLSpinCtrl>("val_spinner_3");
    LLSpinCtrl* spinner4 = getChild<LLSpinCtrl>("val_spinner_4");
    LLColorSwatchCtrl* color_swatch = getChild<LLColorSwatchCtrl>("val_color_swatch");
    LLUICtrl* bool_ctrl = getChild<LLUICtrl>("boolean_combo");

    if (!spinner1 || !spinner2 || !spinner3 || !spinner4 || !color_swatch)
    {
        llwarns << "Could not find all desired controls by name"
                << llendl;
        return;
    }

    spinner1->setVisible(FALSE);
    spinner2->setVisible(FALSE);
    spinner3->setVisible(FALSE);
    spinner4->setVisible(FALSE);
    color_swatch->setVisible(FALSE);
    getChildView("val_text")->setVisible( FALSE);
    mComment->setText(LLStringUtil::null);
    childSetEnabled("copy_btn", false);
    childSetEnabled("default_btn", false);
    bool_ctrl->setVisible(false);

    if (mCurrentControlVariable)
    {
// [RLVa:KB] - Checked: 2011-05-28 (RLVa-1.4.0a) | Modified: RLVa-1.4.0a
        // If "HideFromEditor" was toggled while the floater is open then we need to manually disable access to the control
        mOldVisibility = mCurrentControlVariable->isHiddenFromSettingsEditor();
        spinner1->setEnabled(!mOldVisibility);
        spinner2->setEnabled(!mOldVisibility);
        spinner3->setEnabled(!mOldVisibility);
        spinner4->setEnabled(!mOldVisibility);
        color_swatch->setEnabled(!mOldVisibility);
        childSetEnabled("val_text", !mOldVisibility);
        bool_ctrl->setEnabled(!mOldVisibility);
        childSetEnabled("default_btn", !mOldVisibility);
// [/RLVa:KB]

        childSetEnabled("copy_btn", true);

        eControlType type = mCurrentControlVariable->type();

        mComment->setText(mCurrentControlVariable->getName() + std::string(": ") + mCurrentControlVariable->getComment());

        spinner1->setMaxValue(F32_MAX);
        spinner2->setMaxValue(F32_MAX);
        spinner3->setMaxValue(F32_MAX);
        spinner4->setMaxValue(F32_MAX);
        spinner1->setMinValue(-F32_MAX);
        spinner2->setMinValue(-F32_MAX);
        spinner3->setMinValue(-F32_MAX);
        spinner4->setMinValue(-F32_MAX);
        if (!spinner1->hasFocus())
        {
            spinner1->setIncrement(0.1f);
        }
        if (!spinner2->hasFocus())
        {
            spinner2->setIncrement(0.1f);
        }
        if (!spinner3->hasFocus())
        {
            spinner3->setIncrement(0.1f);
        }
        if (!spinner4->hasFocus())
        {
            spinner4->setIncrement(0.1f);
        }

        LLSD sd = mCurrentControlVariable->get();
        switch(type)
        {
        case TYPE_U32:
            spinner1->setVisible(TRUE);
            spinner1->setLabel(std::string("value")); // Debug, don't translate
            if (!spinner1->hasFocus())
            {
                spinner1->setValue(sd);
                spinner1->setMinValue((F32)U32_MIN);
                spinner1->setMaxValue((F32)U32_MAX);
                spinner1->setIncrement(1.f);
                spinner1->setPrecision(0);
            }
            break;
        case TYPE_S32:
            spinner1->setVisible(TRUE);
            spinner1->setLabel(std::string("value")); // Debug, don't translate
            if (!spinner1->hasFocus())
            {
                spinner1->setValue(sd);
                spinner1->setMinValue((F32)S32_MIN);
                spinner1->setMaxValue((F32)S32_MAX);
                spinner1->setIncrement(1.f);
                spinner1->setPrecision(0);
            }
            break;
        case TYPE_F32:
            spinner1->setVisible(TRUE);
            spinner1->setLabel(std::string("value")); // Debug, don't translate
            if (!spinner1->hasFocus())
            {
                spinner1->setPrecision(3);
                spinner1->setValue(sd);
            }
            break;
        case TYPE_BOOLEAN:
            bool_ctrl->setVisible(true);
            if (!bool_ctrl->hasFocus())
            {
                if (sd.asBoolean())
                {
                    bool_ctrl->setValue(LLSD("TRUE"));
                }
                else
                {
                    bool_ctrl->setValue(LLSD("FALSE"));
                }
            }
            break;
        case TYPE_STRING:
            getChildView("val_text")->setVisible( TRUE);
            if (!getChild<LLUICtrl>("val_text")->hasFocus())
            {
                getChild<LLUICtrl>("val_text")->setValue(sd);
            }
            break;
        case TYPE_VEC3:
        {
            LLVector3 v;
            v.setValue(sd);
            spinner1->setVisible(TRUE);
            spinner1->setLabel(std::string("X"));
            spinner2->setVisible(TRUE);
            spinner2->setLabel(std::string("Y"));
            spinner3->setVisible(TRUE);
            spinner3->setLabel(std::string("Z"));
            if (!spinner1->hasFocus())
            {
                spinner1->setPrecision(3);
                spinner1->setValue(v[VX]);
            }
            if (!spinner2->hasFocus())
            {
                spinner2->setPrecision(3);
                spinner2->setValue(v[VY]);
            }
            if (!spinner3->hasFocus())
            {
                spinner3->setPrecision(3);
                spinner3->setValue(v[VZ]);
            }
            break;
        }
        case TYPE_VEC3D:
        {
            LLVector3d v;
            v.setValue(sd);
            spinner1->setVisible(TRUE);
            spinner1->setLabel(std::string("X"));
            spinner2->setVisible(TRUE);
            spinner2->setLabel(std::string("Y"));
            spinner3->setVisible(TRUE);
            spinner3->setLabel(std::string("Z"));
            if (!spinner1->hasFocus())
            {
                spinner1->setPrecision(3);
                spinner1->setValue(v[VX]);
            }
            if (!spinner2->hasFocus())
            {
                spinner2->setPrecision(3);
                spinner2->setValue(v[VY]);
            }
            if (!spinner3->hasFocus())
            {
                spinner3->setPrecision(3);
                spinner3->setValue(v[VZ]);
            }
            break;
        }
        case TYPE_RECT:
        {
            LLRect r;
            r.setValue(sd);
            spinner1->setVisible(TRUE);
            spinner1->setLabel(std::string("Left"));
            spinner2->setVisible(TRUE);
            spinner2->setLabel(std::string("Right"));
            spinner3->setVisible(TRUE);
            spinner3->setLabel(std::string("Bottom"));
            spinner4->setVisible(TRUE);
            spinner4->setLabel(std::string("Top"));
            if (!spinner1->hasFocus())
            {
                spinner1->setPrecision(0);
                spinner1->setValue(r.mLeft);
            }
            if (!spinner2->hasFocus())
            {
                spinner2->setPrecision(0);
                spinner2->setValue(r.mRight);
            }
            if (!spinner3->hasFocus())
            {
                spinner3->setPrecision(0);
                spinner3->setValue(r.mBottom);
            }
            if (!spinner4->hasFocus())
            {
                spinner4->setPrecision(0);
                spinner4->setValue(r.mTop);
            }

            spinner1->setMinValue((F32)S32_MIN);
            spinner1->setMaxValue((F32)S32_MAX);
            spinner1->setIncrement(1.f);

            spinner2->setMinValue((F32)S32_MIN);
            spinner2->setMaxValue((F32)S32_MAX);
            spinner2->setIncrement(1.f);

            spinner3->setMinValue((F32)S32_MIN);
            spinner3->setMaxValue((F32)S32_MAX);
            spinner3->setIncrement(1.f);

            spinner4->setMinValue((F32)S32_MIN);
            spinner4->setMaxValue((F32)S32_MAX);
            spinner4->setIncrement(1.f);
            break;
        }
        case TYPE_COL4:
        {
            LLColor4 clr;
            clr.setValue(sd);
            color_swatch->setVisible(TRUE);
            // only set if changed so color picker doesn't update
            if(clr != LLColor4(color_swatch->getValue()))
            {
                color_swatch->set(LLColor4(sd), TRUE, FALSE);
            }
            spinner4->setVisible(TRUE);
            spinner4->setLabel(std::string("Alpha"));
            if (!spinner4->hasFocus())
            {
                spinner4->setPrecision(3);
                spinner4->setMinValue(0.0);
                spinner4->setMaxValue(1.f);
                spinner4->setValue(clr.mV[VALPHA]);
            }
            break;
        }
        case TYPE_COL3:
        {
            LLColor3 clr;
            clr.setValue(sd);
            color_swatch->setVisible(TRUE);
            color_swatch->setValue(sd);
            break;
        }
        case TYPE_COL4U:
        {
            LLColor4U clr;
            clr.setValue(sd);
            color_swatch->setVisible(TRUE);
            if(LLColor4(clr) != LLColor4(color_swatch->getValue()))
            {
                color_swatch->set(LLColor4(clr), TRUE, FALSE);
            }
            spinner4->setVisible(TRUE);
            spinner4->setLabel(std::string("Alpha"));
            if(!spinner4->hasFocus())
            {
                spinner4->setPrecision(0);
                spinner4->setValue(clr.mV[VALPHA]);
            }

            spinner4->setMinValue(0);
            spinner4->setMaxValue(255);
            spinner4->setIncrement(1.f);

            break;
        }
        default:
            mComment->setText(std::string("unknown"));
            break;
        }
    }

}
void LLFloaterSettingsDebug::onCommitSettings()
{
    if (!mCurrentControlVariable)
        return;

    LLVector3 vector;
    LLVector3d vectord;
    LLRect rect;
    LLColor4 col4;
    LLColor3 col3;
    LLColor4U col4U;
    LLColor4 color_with_alpha;

    switch(mCurrentControlVariable->type())
    {
    case TYPE_U32:
        mCurrentControlVariable->set(getChild<LLUICtrl>("val_spinner_1")->getValue());
        break;
    case TYPE_S32:
        mCurrentControlVariable->set(getChild<LLUICtrl>("val_spinner_1")->getValue());
        break;
    case TYPE_F32:
        mCurrentControlVariable->set(LLSD(getChild<LLUICtrl>("val_spinner_1")->getValue().asReal()));
        break;
    case TYPE_BOOLEAN:
        mCurrentControlVariable->set(getChild<LLUICtrl>("boolean_combo")->getValue());
        break;
    case TYPE_STRING:
        mCurrentControlVariable->set(LLSD(getChild<LLUICtrl>("val_text")->getValue().asString()));
        break;
    case TYPE_VEC3:
        vector.mV[VX] = (F32)getChild<LLUICtrl>("val_spinner_1")->getValue().asReal();
        vector.mV[VY] = (F32)getChild<LLUICtrl>("val_spinner_2")->getValue().asReal();
        vector.mV[VZ] = (F32)getChild<LLUICtrl>("val_spinner_3")->getValue().asReal();
        mCurrentControlVariable->set(vector.getValue());
        break;
    case TYPE_VEC3D:
        vectord.mdV[VX] = getChild<LLUICtrl>("val_spinner_1")->getValue().asReal();
        vectord.mdV[VY] = getChild<LLUICtrl>("val_spinner_2")->getValue().asReal();
        vectord.mdV[VZ] = getChild<LLUICtrl>("val_spinner_3")->getValue().asReal();
        mCurrentControlVariable->set(vectord.getValue());
        break;
    case TYPE_RECT:
        rect.mLeft = getChild<LLUICtrl>("val_spinner_1")->getValue().asInteger();
        rect.mRight = getChild<LLUICtrl>("val_spinner_2")->getValue().asInteger();
        rect.mBottom = getChild<LLUICtrl>("val_spinner_3")->getValue().asInteger();
        rect.mTop = getChild<LLUICtrl>("val_spinner_4")->getValue().asInteger();
        mCurrentControlVariable->set(rect.getValue());
        break;
    case TYPE_COL4:
        col3.setValue(getChild<LLUICtrl>("val_color_swatch")->getValue());
        col4 = LLColor4(col3, (F32)getChild<LLUICtrl>("val_spinner_4")->getValue().asReal());
        mCurrentControlVariable->set(col4.getValue());
        break;
    case TYPE_COL3:
        mCurrentControlVariable->set(getChild<LLUICtrl>("val_color_swatch")->getValue());
        //col3.mV[VRED] = (F32)getChild<LLUICtrl>("val_spinner_1")->getValue().asC();
        //col3.mV[VGREEN] = (F32)getChild<LLUICtrl>("val_spinner_2")->getValue().asReal();
        //col3.mV[VBLUE] = (F32)getChild<LLUICtrl>("val_spinner_3")->getValue().asReal();
        //mCurrentControlVariable->set(col3.getValue());
        break;
    case TYPE_COL4U:
        col3.setValue(getChild<LLUICtrl>("val_color_swatch")->getValue());
        col4U.setVecScaleClamp(col3);
        col4U.mV[VALPHA] = getChild<LLUICtrl>("val_spinner_4")->getValue().asInteger();
        mCurrentControlVariable->set(col4U.getValue());
        break;
    default:
        break;
    }
}
template <> eControlType get_control_type<LLVector3>(const LLVector3& in, LLSD& out) 
{ 
	out = in.getValue(); 
	return TYPE_VEC3; 
}
//-----------------------------------------------------------------------------
// render()
//-----------------------------------------------------------------------------
void LLHUDEffectLookAt::render()
{
    static const LLCachedControl<bool> private_look_at("PrivateLookAt",false);
    static const LLCachedControl<bool> show_look_at("AscentShowLookAt", false);

    if (private_look_at && (gAgentAvatarp == ((LLVOAvatar*)(LLViewerObject*)mSourceObject)))
        return;

    if (show_look_at && mSourceObject.notNull())
    {
        LLGLDepthTest gls_depth(GL_TRUE,GL_FALSE);

        gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);

        LLVector3 target = mTargetPos + ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->mHeadp->getWorldPosition();
        gGL.matrixMode(LLRender::MM_MODELVIEW);
        gGL.pushMatrix();
        gGL.translatef(target.mV[VX], target.mV[VY], target.mV[VZ]);
        gGL.scalef(0.3f, 0.3f, 0.3f);
        gGL.begin(LLRender::LINES);
        {
            LLColor3 color = (*mAttentions)[mTargetType].mColor;
            gGL.color3f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE]);
            gGL.vertex3f(-1.f, 0.f, 0.f);
            gGL.vertex3f(1.f, 0.f, 0.f);

            gGL.vertex3f(0.f, -1.f, 0.f);
            gGL.vertex3f(0.f, 1.f, 0.f);

            gGL.vertex3f(0.f, 0.f, -1.f);
            gGL.vertex3f(0.f, 0.f, 1.f);
        }
        gGL.end();
        gGL.popMatrix();
        // <edit>
        const std::string text = ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->getFullname();
        LLVector3 offset = gAgentCamera.getCameraPositionAgent() - target;
        offset.normalize();
        LLVector3 shadow_offset = offset * 0.49f;
        offset *= 0.5f;
        const LLFontGL* font = LLResMgr::getInstance()->getRes(LLFONT_SANSSERIF);
        LLGLEnable gl_blend(GL_BLEND);
        gGL.pushMatrix();
        gViewerWindow->setup2DViewport();
        hud_render_utf8text(text,
                            target + shadow_offset,
                            *font,
                            LLFontGL::NORMAL,
                            LLFontGL::NO_SHADOW,
                            -0.5f * font->getWidthF32(text) + 2.0f,
                            -2.0f,
                            LLColor4::black,
                            FALSE);
        hud_render_utf8text(text,
                            target + offset,
                            *font,
                            LLFontGL::NORMAL,
                            LLFontGL::NO_SHADOW,
                            -0.5f * font->getWidthF32(text),
                            0.0f,
                            (*mAttentions)[mTargetType].mColor,
                            FALSE);
        gGL.popMatrix();
        // </edit>
    }
}
//-----------------------------------------------------------------------------
// solve()
//-----------------------------------------------------------------------------
void LLJointSolverRP3::solve()
{
//	LL_INFOS() << LL_ENDL;
//	LL_INFOS() << "LLJointSolverRP3::solve()" << LL_ENDL;

	//-------------------------------------------------------------------------
	// setup joints in their base rotations
	//-------------------------------------------------------------------------
	mJointA->setRotation( mJointABaseRotation );
	mJointB->setRotation( mJointBBaseRotation );

	//-------------------------------------------------------------------------
	// get joint positions in world space
	//-------------------------------------------------------------------------
	LLVector3 aPos = mJointA->getWorldPosition();
	LLVector3 bPos = mJointB->getWorldPosition();
	LLVector3 cPos = mJointC->getWorldPosition();
	LLVector3 gPos = mJointGoal->getWorldPosition();

//	LL_INFOS() << "bPosLocal = " << mJointB->getPosition() << LL_ENDL;
//	LL_INFOS() << "cPosLocal = " << mJointC->getPosition() << LL_ENDL;
//	LL_INFOS() << "bRotLocal = " << mJointB->getRotation() << LL_ENDL;
//	LL_INFOS() << "cRotLocal = " << mJointC->getRotation() << LL_ENDL;

//	LL_INFOS() << "aPos : " << aPos << LL_ENDL;
//	LL_INFOS() << "bPos : " << bPos << LL_ENDL;
//	LL_INFOS() << "cPos : " << cPos << LL_ENDL;
//	LL_INFOS() << "gPos : " << gPos << LL_ENDL;

	//-------------------------------------------------------------------------
	// get the poleVector in world space
	//-------------------------------------------------------------------------
	LLVector3 poleVec = mPoleVector;
	if ( mJointA->getParent() )
	{
		LLVector4a pole_veca;
		pole_veca.load3(mPoleVector.mV);
		mJointA->getParent()->getWorldMatrix().rotate(pole_veca,pole_veca);
		poleVec.set(pole_veca.getF32ptr());
	}

	//-------------------------------------------------------------------------
	// compute the following:
	// vector from A to B
	// vector from B to C
	// vector from A to C
	// vector from A to G (goal)
	//-------------------------------------------------------------------------
	LLVector3 abVec = bPos - aPos;
	LLVector3 bcVec = cPos - bPos;
	LLVector3 acVec = cPos - aPos;
	LLVector3 agVec = gPos - aPos;

//	LL_INFOS() << "abVec : " << abVec << LL_ENDL;
//	LL_INFOS() << "bcVec : " << bcVec << LL_ENDL;
//	LL_INFOS() << "acVec : " << acVec << LL_ENDL;
//	LL_INFOS() << "agVec : " << agVec << LL_ENDL;

	//-------------------------------------------------------------------------
	// compute needed lengths of those vectors
	//-------------------------------------------------------------------------
	F32 abLen = abVec.magVec();
	F32 bcLen = bcVec.magVec();
	F32 agLen = agVec.magVec();

//	LL_INFOS() << "abLen : " << abLen << LL_ENDL;
//	LL_INFOS() << "bcLen : " << bcLen << LL_ENDL;
//	LL_INFOS() << "agLen : " << agLen << LL_ENDL;

	//-------------------------------------------------------------------------
	// compute component vector of (A->B) orthogonal to (A->C)
	//-------------------------------------------------------------------------
	LLVector3 abacCompOrthoVec = abVec - acVec * ((abVec * acVec)/(acVec * acVec));

//	LL_INFOS() << "abacCompOrthoVec : " << abacCompOrthoVec << LL_ENDL;

	//-------------------------------------------------------------------------
	// compute the normal of the original ABC plane (and store for later)
	//-------------------------------------------------------------------------
	LLVector3 abcNorm;
	if (!mbUseBAxis)
	{
		if( are_parallel(abVec, bcVec, 0.001f) )
		{
			// the current solution is maxed out, so we use the axis that is
			// orthogonal to both poleVec and A->B
			if ( are_parallel(poleVec, abVec, 0.001f) )
			{
				// ACK! the problem is singular
				if ( are_parallel(poleVec, agVec, 0.001f) )
				{
					// the solutions is also singular
					return;
				}
				else
				{
					abcNorm = poleVec % agVec;
				}
			}
			else
			{
				abcNorm = poleVec % abVec;
			}
		}
		else
		{
			abcNorm = abVec % bcVec;
		}
	}
	else
	{
		abcNorm = mBAxis * mJointB->getWorldRotation();
	}

	//-------------------------------------------------------------------------
	// compute rotation of B
	//-------------------------------------------------------------------------
	// angle between A->B and B->C
	F32 abbcAng = angle_between(abVec, bcVec);

	// vector orthogonal to A->B and B->C
	LLVector3 abbcOrthoVec = abVec % bcVec;
	if (abbcOrthoVec.magVecSquared() < 0.001f)
	{
		abbcOrthoVec = poleVec % abVec;
		abacCompOrthoVec = poleVec;
	}
	abbcOrthoVec.normVec();

	F32 agLenSq = agLen * agLen;

	// angle arm for extension
	F32 cosTheta =	(agLenSq - abLen*abLen - bcLen*bcLen) / (2.0f * abLen * bcLen);
	if (cosTheta > 1.0f)
		cosTheta = 1.0f;
	else if (cosTheta < -1.0f)
		cosTheta = -1.0f;

	F32 theta = acos(cosTheta);

	LLQuaternion bRot(theta - abbcAng, abbcOrthoVec);

//	LL_INFOS() << "abbcAng      : " << abbcAng << LL_ENDL;
//	LL_INFOS() << "abbcOrthoVec : " << abbcOrthoVec << LL_ENDL;
//	LL_INFOS() << "agLenSq      : " << agLenSq << LL_ENDL;
//	LL_INFOS() << "cosTheta     : " << cosTheta << LL_ENDL;
//	LL_INFOS() << "theta        : " << theta << LL_ENDL;
//	LL_INFOS() << "bRot         : " << bRot << LL_ENDL;
//	LL_INFOS() << "theta abbcAng theta-abbcAng: " << theta*180.0/F_PI << " " << abbcAng*180.0f/F_PI << " " << (theta - abbcAng)*180.0f/F_PI << LL_ENDL;

	//-------------------------------------------------------------------------
	// compute rotation that rotates new A->C to A->G
	//-------------------------------------------------------------------------
	// rotate B->C by bRot
	bcVec = bcVec * bRot;

	// update A->C
	acVec = abVec + bcVec;

	LLQuaternion cgRot;
	cgRot.shortestArc( acVec, agVec );

//	LL_INFOS() << "bcVec : " << bcVec << LL_ENDL;
//	LL_INFOS() << "acVec : " << acVec << LL_ENDL;
//	LL_INFOS() << "cgRot : " << cgRot << LL_ENDL;

	// update A->B and B->C with rotation from C to G
	abVec = abVec * cgRot;
	bcVec = bcVec * cgRot;
	abcNorm = abcNorm * cgRot;
	acVec = abVec + bcVec;

	//-------------------------------------------------------------------------
	// compute the normal of the APG plane
	//-------------------------------------------------------------------------
	if (are_parallel(agVec, poleVec, 0.001f))
	{
		// the solution plane is undefined ==> we're done
		return;
	}
	LLVector3 apgNorm = poleVec % agVec;
	apgNorm.normVec();

	if (!mbUseBAxis)
	{
		//---------------------------------------------------------------------
		// compute the normal of the new ABC plane
		// (only necessary if we're NOT using mBAxis)
		//---------------------------------------------------------------------
		if( are_parallel(abVec, bcVec, 0.001f) )
		{
			// G is either too close or too far away
			// we'll use the old ABCnormal 
		}
		else
		{
			abcNorm = abVec % bcVec;
		}
		abcNorm.normVec();
	}

	//-------------------------------------------------------------------------
	// calcuate plane rotation
	//-------------------------------------------------------------------------
	LLQuaternion pRot;
	if ( are_parallel( abcNorm, apgNorm, 0.001f) )
	{
		if (abcNorm * apgNorm < 0.0f)
		{
			// we must be PI radians off ==> rotate by PI around agVec
			pRot.setQuat(F_PI, agVec);
		}
		else
		{
			// we're done
		}
	}
	else
	{
		pRot.shortestArc( abcNorm, apgNorm );
	}

//	LL_INFOS() << "abcNorm = " << abcNorm << LL_ENDL;
//	LL_INFOS() << "apgNorm = " << apgNorm << LL_ENDL;
//	LL_INFOS() << "pRot = " << pRot << LL_ENDL;

	//-------------------------------------------------------------------------
	// compute twist rotation
	//-------------------------------------------------------------------------
	LLQuaternion twistRot( mTwist, agVec );

//	LL_INFOS() << "twist    : " << mTwist*180.0/F_PI << LL_ENDL;
//	LL_INFOS() << "agNormVec: " << agNormVec << LL_ENDL;
//	LL_INFOS() << "twistRot : " << twistRot << LL_ENDL;

	//-------------------------------------------------------------------------
	// compute rotation of A
	//-------------------------------------------------------------------------
	LLQuaternion aRot = cgRot * pRot * twistRot;

	//-------------------------------------------------------------------------
	// apply the rotations
	//-------------------------------------------------------------------------
	mJointB->setWorldRotation( mJointB->getWorldRotation() * bRot );
	mJointA->setWorldRotation( mJointA->getWorldRotation() * aRot );
}
Beispiel #17
0
void LLBBox::addPointAgent( LLVector3 p)
{
	p -= mPosAgent;
	p.rotVec( ~mRotation );
	addPointLocal( p );
}
BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
									  LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
	
{

	if (!lineSegmentBoundingBox(start, end))
	{
		return FALSE;
	}

	LLVector4a da;
	da.setSub(end, start);
	LLVector3 delta(da.getF32ptr());
		
	LLVector3 pdelta = delta;
	pdelta.mV[2] = 0;

	F32 plength = pdelta.length();
	
	F32 tdelta = 1.f/plength;

	LLVector3 v_start(start.getF32ptr());

	LLVector3 origin = v_start - mRegionp->getOriginAgent();

	if (mRegionp->getLandHeightRegion(origin) > origin.mV[2])
	{
		//origin is under ground, treat as no intersection
		return FALSE;
	}

	//step one meter at a time until intersection point found

	//VECTORIZE THIS
	const LLVector4a* exta = mDrawable->getSpatialExtents();

	LLVector3 ext[2];
	ext[0].set(exta[0].getF32ptr());
	ext[1].set(exta[1].getF32ptr());

	F32 rad = (delta*tdelta).magVecSquared();

	F32 t = 0.f;
	while ( t <= 1.f)
	{
		LLVector3 sample = origin + delta*t;
		
		if (AABBSphereIntersectR2(ext[0], ext[1], sample+mRegionp->getOriginAgent(), rad))
		{
			F32 height = mRegionp->getLandHeightRegion(sample);
			if (height > sample.mV[2])
			{ //ray went below ground, positive intersection
				//quick and dirty binary search to get impact point
				tdelta = -tdelta*0.5f;
				F32 err_dist = 0.001f;
				F32 dist = fabsf(sample.mV[2] - height);

				while (dist > err_dist && tdelta*tdelta > 0.0f)
				{
					t += tdelta;
					sample = origin+delta*t;
					height = mRegionp->getLandHeightRegion(sample);
					if ((tdelta < 0 && height < sample.mV[2]) ||
						(height > sample.mV[2] && tdelta > 0))
					{ //jumped over intersection point, go back
						tdelta = -tdelta;
					}
					tdelta *= 0.5f;
					dist = fabsf(sample.mV[2] - height);
				}

				if (intersection)
				{
					F32 height = mRegionp->getLandHeightRegion(sample);
					if (fabsf(sample.mV[2]-height) < delta.length()*tdelta)
					{
						sample.mV[2] = mRegionp->getLandHeightRegion(sample);
					}
					intersection->load3((sample + mRegionp->getOriginAgent()).mV);
				}

				if (normal)
				{
					normal->load3((mRegionp->getLand().resolveNormalGlobal(mRegionp->getPosGlobalFromRegion(sample))).mV);
				}

				return TRUE;
			}
		}

		t += tdelta;
		if (t > 1 && t < 1.f+tdelta*0.99f)
		{ //make sure end point is checked (saves vertical lines coming up negative)
			t = 1.f;
		}
	}


	return FALSE;
}
// 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 #20
0
BOOL LLControlGroup::declareVec3(const std::string& name, const LLVector3 &initial_val, const std::string& comment, BOOL persist)
{
	return declareControl(name, TYPE_VEC3, initial_val.getValue(), comment, persist);
}
Beispiel #21
0
// -----------------------------------------------------------------------------
void LLViewerJoystick::moveObjects(bool reset)
{
	static bool toggle_send_to_sim = false;

	if (!gFocusMgr.getAppHasFocus() || mDriverState != JDS_INITIALIZED
		|| !gSavedSettings.getBOOL("JoystickEnabled") || !gSavedSettings.getBOOL("JoystickBuildEnabled"))
	{
		return;
	}

	S32 axis[] = 
	{
		gSavedSettings.getS32("JoystickAxis0"),
		gSavedSettings.getS32("JoystickAxis1"),
		gSavedSettings.getS32("JoystickAxis2"),
		gSavedSettings.getS32("JoystickAxis3"),
		gSavedSettings.getS32("JoystickAxis4"),
		gSavedSettings.getS32("JoystickAxis5"),
	};

	if (reset || mResetFlag)
	{
		resetDeltas(axis);
		return;
	}

	F32 axis_scale[] =
	{
		gSavedSettings.getF32("BuildAxisScale0"),
		gSavedSettings.getF32("BuildAxisScale1"),
		gSavedSettings.getF32("BuildAxisScale2"),
		gSavedSettings.getF32("BuildAxisScale3"),
		gSavedSettings.getF32("BuildAxisScale4"),
		gSavedSettings.getF32("BuildAxisScale5"),
	};

	F32 dead_zone[] =
	{
		gSavedSettings.getF32("BuildAxisDeadZone0"),
		gSavedSettings.getF32("BuildAxisDeadZone1"),
		gSavedSettings.getF32("BuildAxisDeadZone2"),
		gSavedSettings.getF32("BuildAxisDeadZone3"),
		gSavedSettings.getF32("BuildAxisDeadZone4"),
		gSavedSettings.getF32("BuildAxisDeadZone5"),
	};

	F32 cur_delta[6];
	F32 time = gFrameIntervalSeconds;

	// avoid making ridicously big movements if there's a big drop in fps 
	if (time > .2f)
	{
		time = .2f;
	}

	// max feather is 32
	F32 feather = gSavedSettings.getF32("BuildFeathering"); 
	bool is_zero = true, absolute = gSavedSettings.getBOOL("Cursor3D");
	
	for (U32 i = 0; i < 6; i++)
	{
		cur_delta[i] = -mAxes[axis[i]];
		F32 tmp = cur_delta[i];
		if (absolute)
		{
			cur_delta[i] = cur_delta[i] - sLastDelta[i];
		}
		sLastDelta[i] = tmp;
		is_zero = is_zero && (cur_delta[i] == 0.f);
			
		if (cur_delta[i] > 0)
		{
			cur_delta[i] = llmax(cur_delta[i]-dead_zone[i], 0.f);
		}
		else
		{
			cur_delta[i] = llmin(cur_delta[i]+dead_zone[i], 0.f);
		}
		cur_delta[i] *= axis_scale[i];
		
		if (!absolute)
		{
			cur_delta[i] *= time;
		}

		sDelta[i] = sDelta[i] + (cur_delta[i]-sDelta[i])*time*feather;
	}

	U32 upd_type = UPD_NONE;
	LLVector3 v;
    
	if (!is_zero)
	{
		if (sDelta[0] || sDelta[1] || sDelta[2])
		{
			upd_type |= UPD_POSITION;
			v.setVec(sDelta[0], sDelta[1], sDelta[2]);
		}
		
		if (sDelta[3] || sDelta[4] || sDelta[5])
		{
			upd_type |= UPD_ROTATION;
		}
				
		// the selection update could fail, so we won't send 
		if (LLSelectMgr::getInstance()->selectionMove(v, sDelta[3],sDelta[4],sDelta[5], upd_type))
		{
			toggle_send_to_sim = true;
		}
	}
	else if (toggle_send_to_sim)
	{
		LLSelectMgr::getInstance()->sendSelectionMove();
		toggle_send_to_sim = false;
	}
}
Beispiel #22
0
// Returns number of controls loaded, so 0 if failure
U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, BOOL require_declaration, eControlType declare_as)
{
	std::string name;

	LLXmlTree xml_controls;

	if (!xml_controls.parseFile(filename))
	{
		llwarns << "Unable to open control file " << filename << llendl;
		return 0;
	}

	LLXmlTreeNode* rootp = xml_controls.getRoot();
	if (!rootp || !rootp->hasAttribute("version"))
	{
		llwarns << "No valid settings header found in control file " << filename << llendl;
		return 0;
	}

	U32		item = 0;
	U32		validitems = 0;
	S32 version;
	
	rootp->getAttributeS32("version", version);

	// Check file version
	if (version != CURRENT_VERSION)
	{
		llinfos << filename << " does not appear to be a version " << CURRENT_VERSION << " controls file" << llendl;
		return 0;
	}

	LLXmlTreeNode* child_nodep = rootp->getFirstChild();
	while(child_nodep)
	{
		name = child_nodep->getName();		
		
		BOOL declared = controlExists(name);

		if (require_declaration && !declared)
		{
			// Declaration required, but this name not declared.
			// Complain about non-empty names.
			if (!name.empty())
			{
				//read in to end of line
				llwarns << "LLControlGroup::loadFromFile() : Trying to set \"" << name << "\", setting doesn't exist." << llendl;
			}
			child_nodep = rootp->getNextChild();
			continue;
		}

		// Got an item.  Load it up.
		item++;

		// If not declared, assume it's a string
		if (!declared)
		{
			switch(declare_as)
			{
			case TYPE_COL4:
				declareColor4(name, LLColor4::white, LLStringUtil::null, NO_PERSIST);
				break;
			case TYPE_COL4U:
				declareColor4U(name, LLColor4U::white, LLStringUtil::null, NO_PERSIST);
				break;
			case TYPE_STRING:
			default:
				declareString(name, LLStringUtil::null, LLStringUtil::null, NO_PERSIST);
				break;
			}
		}

		// Control name has been declared in code.
		LLControlVariable *control = getControl(name);

		llassert(control);
		
		switch(control->mType)
		{
		case TYPE_F32:
			{
				F32 initial = 0.f;

				child_nodep->getAttributeF32("value", initial);

				control->set(initial);
				validitems++;
			}
			break;
		case TYPE_S32:
			{
				S32 initial = 0;

				child_nodep->getAttributeS32("value", initial);

				control->set(initial);
				validitems++;
			}
			break;
		case TYPE_U32:
			{
				U32 initial = 0;
				child_nodep->getAttributeU32("value", initial);
				control->set((LLSD::Integer) initial);
				validitems++;
			}
			break;
		case TYPE_BOOLEAN:
			{
				BOOL initial = FALSE;

				child_nodep->getAttributeBOOL("value", initial);
				control->set(initial);

				validitems++;
			}
			break;
		case TYPE_STRING:
			{
				std::string string;
				child_nodep->getAttributeString("value", string);
				control->set(string);
				validitems++;
			}
			break;
		case TYPE_VEC3:
			{
				LLVector3 vector;

				child_nodep->getAttributeVector3("value", vector);
				control->set(vector.getValue());
				validitems++;
			}
			break;
		case TYPE_VEC3D:
			{
				LLVector3d vector;

				child_nodep->getAttributeVector3d("value", vector);

				control->set(vector.getValue());
				validitems++;
			}
			break;
		case TYPE_RECT:
			{
				//RN: hack to support reading rectangles from a string
				std::string rect_string;

				child_nodep->getAttributeString("value", rect_string);
				std::istringstream istream(rect_string);
				S32 left, bottom, width, height;

				istream >> left >> bottom >> width >> height;

				LLRect rect;
				rect.setOriginAndSize(left, bottom, width, height);

				control->set(rect.getValue());
				validitems++;
			}
			break;
		case TYPE_COL4U:
			{
				LLColor4U color;

				child_nodep->getAttributeColor4U("value", color);
				control->set(color.getValue());
				validitems++;
			}
			break;
		case TYPE_COL4:
			{
				LLColor4 color;
				
				child_nodep->getAttributeColor4("value", color);
				control->set(color.getValue());
				validitems++;
			}
			break;
		case TYPE_COL3:
			{
				LLVector3 color;
				
				child_nodep->getAttributeVector3("value", color);
				control->set(LLColor3(color.mV).getValue());
				validitems++;
			}
			break;

		default:
		  break;

		}
	
		child_nodep = rootp->getNextChild();
	}

	return validitems;
}
Beispiel #23
0
BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
{
	LLFastTimer ftm(LLFastTimer::FTM_GEO_SKY);
	LLStrider<LLVector3>	vertices;
	LLStrider<LLVector2>	texCoords;
	LLStrider<U16>			indices;

#if DOME_SLICES
	{
		mFanVerts = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB);
		mFanVerts->allocateBuffer(getFanNumVerts(), getFanNumIndices(), TRUE);

		BOOL success = mFanVerts->getVertexStrider(vertices)
			&& mFanVerts->getTexCoord0Strider(texCoords)
			&& mFanVerts->getIndexStrider(indices);

		if(!success) 
		{
			llerrs << "Failed updating WindLight sky geometry." << llendl;
		}

		buildFanBuffer(vertices, texCoords, indices);

		mFanVerts->flush();
	}

	{
		const U32 max_buffer_bytes = gSavedSettings.getS32("RenderMaxVBOSize")*1024;
		const U32 data_mask = LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK;
		const U32 max_verts = max_buffer_bytes / LLVertexBuffer::calcVertexSize(data_mask);

		const U32 total_stacks = getNumStacks();

		const U32 verts_per_stack = getNumSlices();

		// each seg has to have one more row of verts than it has stacks
		// then round down
		const U32 stacks_per_seg = (max_verts - verts_per_stack) / verts_per_stack;

		// round up to a whole number of segments
		const U32 strips_segments = (total_stacks+stacks_per_seg-1) / stacks_per_seg;

		llinfos << "WL Skydome strips in " << strips_segments << " batches." << llendl;

		mStripsVerts.resize(strips_segments, NULL);
		LLTimer timer;
		timer.start();

		for (U32 i = 0; i < strips_segments ;++i)
		{
			LLVertexBuffer * segment = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB);
			mStripsVerts[i] = segment;

			U32 num_stacks_this_seg = stacks_per_seg;
			if ((i == strips_segments - 1) && (total_stacks % stacks_per_seg) != 0)
			{
				// for the last buffer only allocate what we'll use
				num_stacks_this_seg = total_stacks % stacks_per_seg;
			}

			// figure out what range of the sky we're filling
			const U32 begin_stack = i * stacks_per_seg;
			const U32 end_stack = begin_stack + num_stacks_this_seg;
			llassert(end_stack <= total_stacks);

			const U32 num_verts_this_seg = verts_per_stack * (num_stacks_this_seg+1);
			llassert(num_verts_this_seg <= max_verts);

			const U32 num_indices_this_seg = 1+num_stacks_this_seg*(2+2*verts_per_stack);
			llassert(num_indices_this_seg * sizeof(U16) <= max_buffer_bytes);

			segment->allocateBuffer(num_verts_this_seg, num_indices_this_seg, TRUE);

			// lock the buffer
			BOOL success = segment->getVertexStrider(vertices)
				&& segment->getTexCoord0Strider(texCoords)
				&& segment->getIndexStrider(indices);

			if(!success) 
			{
				llerrs << "Failed updating WindLight sky geometry." << llendl;
			}

			// fill it
			buildStripsBuffer(begin_stack, end_stack,  vertices, texCoords, indices);

			// and unlock the buffer
			segment->flush();
		}
		llinfos << "completed in " << llformat("%.2f", timer.getElapsedTimeF32()) << "seconds" << llendl;
	}
#else
	mStripsVerts = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB);
	
	const F32 RADIUS = LLWLParamManager::sParamMgr->getDomeRadius();

	LLPointer<LLVertexBuffer> temp = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, 0);
	temp->allocateBuffer(12, 60, TRUE);

	BOOL success = temp->getVertexStrider(vertices)
		&& temp->getIndexStrider(indices);

	if (success)
	{
		for (U32 i = 0; i < 12; i++)
		{
			*vertices++ = icosahedron_vert[i];
		}

		for (U32 i = 0; i < 60; i++)
		{
			*indices++ = icosahedron_ind[i];
		}
	}


	LLPointer<LLVertexBuffer> temp2;
	
	for (U32 i = 0; i < 8; i++)
	{
		temp2 = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, 0);
		subdivide(*temp, temp2);
		temp = temp2;
	}
	
	temp->getVertexStrider(vertices);
	for (S32 i = 0; i < temp->getNumVerts(); i++)
	{
		LLVector3 v = vertices[i];
		v.normVec();
		vertices[i] = v*RADIUS;
	}

	temp2 = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, 0);
	chop(*temp, temp2);

	mStripsVerts->allocateBuffer(temp2->getNumVerts(), temp2->getNumIndices(), TRUE);
	
	success = mStripsVerts->getVertexStrider(vertices)
		&& mStripsVerts->getTexCoordStrider(texCoords)
		&& mStripsVerts->getIndexStrider(indices);

	LLStrider<LLVector3> v;
	temp2->getVertexStrider(v);
	LLStrider<U16> ind;
	temp2->getIndexStrider(ind);

	if (success)
	{
		for (S32 i = 0; i < temp2->getNumVerts(); ++i)
		{
			LLVector3 vert = *v++;
			vert.normVec();
			F32 z0 = vert.mV[2];
			F32 x0 = vert.mV[0];
			
			vert *= RADIUS;
			
			*vertices++ = vert;
			*texCoords++ = LLVector2((-z0 + 1.f) / 2.f, (-x0 + 1.f) / 2.f);
		}

		for (S32 i = 0; i < temp2->getNumIndices(); ++i)
		{
			*indices++ = *ind++;
		}
	}

	mStripsVerts->flush();
#endif

	updateStarColors();
	updateStarGeometry(drawable);

	LLPipeline::sCompiles++;

	return TRUE;
}
void LLWaterParamManager::update(LLViewerCamera * cam)
{
	LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WLPARAM);
	
	// update the shaders and the menu
	propagateParameters();
	
	// sync menus if they exist
	if(LLFloaterWater::isOpen()) 
	{
		LLFloaterWater::instance()->syncMenu();
	}

	stop_glerror();

	// only do this if we're dealing with shaders
	if(gPipeline.canUseVertexShaders()) 
	{
		//transform water plane to eye space
		glh::vec3f norm(0.f, 0.f, 1.f);
		glh::vec3f p(0.f, 0.f, gAgent.getRegion()->getWaterHeight()+0.1f);
		
		F32 modelView[16];
		for (U32 i = 0; i < 16; i++)
		{
			modelView[i] = (F32) gGLModelView[i];
		}

		glh::matrix4f mat(modelView);
		glh::matrix4f invtrans = mat.inverse().transpose();
		glh::vec3f enorm;
		glh::vec3f ep;
		invtrans.mult_matrix_vec(norm, enorm);
		enorm.normalize();
		mat.mult_matrix_vec(p, ep);

		mWaterPlane = LLVector4(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm));

		if((mWaterPlane.mV[3] >= 0.f) == LLViewerCamera::getInstance()->cameraUnderWater()) //Sign borkage..
		{
			mWaterPlane.scaleVec(LLVector4(-1.f,-1.f,-1.f,-1.f));
		}

		LLVector3 sunMoonDir;
		if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS) 	 
		{ 	 
			sunMoonDir = gSky.getSunDirection(); 	 
		} 	 
		else  	 
		{ 	 
			sunMoonDir = gSky.getMoonDirection(); 	 
		}
		sunMoonDir.normVec();
		mWaterFogKS = 1.f/llmax(sunMoonDir.mV[2], WATER_FOG_LIGHT_CLAMP);

		std::vector<LLGLSLShader*>::iterator shaders_iter=mShaderList.begin();
		for(; shaders_iter != mShaderList.end(); ++shaders_iter)
		{
			(*shaders_iter)->mUniformsDirty = TRUE;
		}
	}
}
void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
{
	if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD)
	{
		LL_WARNS() << "Attempted to update distance for non-world camera." << LL_ENDL;
		return;
	}

	if (gShiftFrame)
	{
		return;
	}

	//switch LOD with the spatial group to avoid artifacts
	//LLSpatialGroup* sg = getSpatialGroup();

	LLVector3 pos;

	//if (!sg || sg->changeLOD())
	{
		LLVOVolume* volume = getVOVolume();
		if (volume)
		{
			if (getGroup())
			{
				pos.set(getPositionGroup().getF32ptr());
			}
			else
			{
				pos = getPositionAgent();
			}
			
			if (isState(LLDrawable::HAS_ALPHA))
			{
				for (S32 i = 0; i < getNumFaces(); i++)
				{
					LLFace* facep = getFace(i);
					if (facep && 
						(force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA))
					{
						LLVector4a box;
						box.setSub(facep->mExtents[1], facep->mExtents[0]);
						box.mul(0.25f);
						LLVector3 v = (facep->mCenterLocal-camera.getOrigin());
						const LLVector3& at = camera.getAtAxis();
						for (U32 j = 0; j < 3; j++)
						{
							v.mV[j] -= box[j] * at.mV[j];
						}
						facep->mDistance = v * camera.getAtAxis();
					}
				}
			}
		}
		else
		{
			pos = LLVector3(getPositionGroup().getF32ptr());
		}

		pos -= camera.getOrigin();	
		mDistanceWRTCamera = ll_round(pos.magVec(), 0.01f);
		mVObjp->updateLOD();
	}
}
void LLWaterParamManager::update(LLViewerCamera * cam)
{
	LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WLPARAM);
	
	// update the shaders and the menu
	propagateParameters();
	
	// sync menus if they exist
	if(LLFloaterWater::isOpen()) 
	{
		LLFloaterWater::instance()->syncMenu();
	}

	//stop_glerror();
	// only do this if we're dealing with shaders
	if(gPipeline.canUseVertexShaders()) 
	{
		//transform water plane to eye space
		glh::vec3f norm(0.f, 0.f, 1.f);
		glh::vec3f p(0.f, 0.f, gAgent.getRegion()->getWaterHeight()+0.1f);
		
		F32 modelView[16];
		for (U32 i = 0; i < 16; i++)
		{
			modelView[i] = (F32) gGLModelView[i];
		}

		glh::matrix4f mat(modelView);
		glh::matrix4f invtrans = mat.inverse().transpose();
		glh::vec3f enorm;
		glh::vec3f ep;
		invtrans.mult_matrix_vec(norm, enorm);
		enorm.normalize();
		mat.mult_matrix_vec(p, ep);

		mWaterPlane = LLVector4(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm));

		LLVector3 sunMoonDir;
		if (gSky.getSunDirection().mV[2] > NIGHTTIME_ELEVATION_COS) 	 
		{ 	 
			sunMoonDir = gSky.getSunDirection(); 	 
		} 	 
		else  	 
		{ 	 
			sunMoonDir = gSky.getMoonDirection(); 	 
		}
		sunMoonDir.normVec();
		mWaterFogKS = 1.f/llmax(sunMoonDir.mV[2], WATER_FOG_LIGHT_CLAMP);

		LLViewerShaderMgr::shader_iter shaders_iter, end_shaders;
		end_shaders = LLViewerShaderMgr::instance()->endShaders();
		for(shaders_iter = LLViewerShaderMgr::instance()->beginShaders(); shaders_iter != end_shaders; ++shaders_iter)
		{
			if (shaders_iter->mProgramObject != 0
				&& shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER)
			{
				shaders_iter->mUniformsDirty = TRUE;
			}
		}
	}
}
BOOL LLToolPlacer::addObject( LLPCode pcode, S32 x, S32 y, U8 use_physics )
{
	LLVector3 ray_start_region;
	LLVector3 ray_end_region;
	LLViewerRegion* regionp = NULL;
	BOOL b_hit_land = FALSE;
	S32 hit_face = -1;
	LLViewerObject* hit_obj = NULL;
	U8 state = 0;
	BOOL success = raycastForNewObjPos( x, y, &hit_obj, &hit_face, &b_hit_land, &ray_start_region, &ray_end_region, &regionp );
	if( !success )
	{
		return FALSE;
	}

	if( hit_obj && (hit_obj->isAvatar() || hit_obj->isAttachment()) )
	{
		// Can't create objects on avatars or attachments
		return FALSE;
	}

	if (NULL == regionp)
	{
		llwarns << "regionp was NULL; aborting function." << llendl;
		return FALSE;
	}

	if (regionp->getRegionFlag(REGION_FLAGS_SANDBOX))
	{
		//LLFirstUse::useSandbox();
	}

	// Set params for new object based on its PCode.
	LLQuaternion	rotation;
	LLVector3		scale = LLVector3(
		gSavedSettings.getF32("FSBuildPrefs_Xsize"),
		gSavedSettings.getF32("FSBuildPrefs_Ysize"),
		gSavedSettings.getF32("FSBuildPrefs_Zsize"));

	U8				material = LL_MCODE_WOOD;
	const std::string default_material = gSavedSettings.getString("FSBuildPrefs_Material");
	if (default_material == "Wood")			material = LL_MCODE_WOOD;
	else if (default_material == "Stone")	material = LL_MCODE_STONE;
	else if (default_material == "Metal")	material = LL_MCODE_METAL;
	else if (default_material == "Glass")	material = LL_MCODE_GLASS;
	else if (default_material == "Flesh")	material = LL_MCODE_FLESH;
	else if (default_material == "Rubber")	material = LL_MCODE_RUBBER;
	else if (default_material == "Plastic")	material = LL_MCODE_PLASTIC;

	BOOL			create_selected = FALSE;
	LLVolumeParams	volume_params;
	
	switch (pcode) 
	{
	case LL_PCODE_LEGACY_GRASS:
		//  Randomize size of grass patch 
		scale.setVec(10.f + ll_frand(20.f), 10.f + ll_frand(20.f),  1.f + ll_frand(2.f));
		state = rand() % LLVOGrass::sMaxGrassSpecies;
		break;


	case LL_PCODE_LEGACY_TREE:
	case LL_PCODE_TREE_NEW:
		state = rand() % LLVOTree::sMaxTreeSpecies;
		break;

	case LL_PCODE_SPHERE:
	case LL_PCODE_CONE:
	case LL_PCODE_CUBE:
	case LL_PCODE_CYLINDER:
	case LL_PCODE_TORUS:
	case LLViewerObject::LL_VO_SQUARE_TORUS:
	case LLViewerObject::LL_VO_TRIANGLE_TORUS:
	default:
		create_selected = TRUE;
		break;
	}

	// Play creation sound
	// <FS:PP> Configurable UI sounds
	//if (gAudiop)
	if (gAudiop && gSavedSettings.getBOOL("PlayModeUISndObjectCreate"))
	// </FS:PP>
	{
		gAudiop->triggerSound( LLUUID(gSavedSettings.getString("UISndObjectCreate")),
								gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI);
	}

	gMessageSystem->newMessageFast(_PREHASH_ObjectAdd);
	gMessageSystem->nextBlockFast(_PREHASH_AgentData);
	gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
	gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
	LLUUID group_id = gAgent.getGroupID();
	LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
	if (gSavedSettings.getBOOL("RezUnderLandGroup"))
	{
		if (gAgent.isInGroup(parcel->getGroupID()))
		{
			group_id = parcel->getGroupID();
		}
		else if (gAgent.isInGroup(parcel->getOwnerID()))
		{
			group_id = parcel->getOwnerID();
		}
	}
	gMessageSystem->addUUIDFast(_PREHASH_GroupID, group_id);
	gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
	gMessageSystem->addU8Fast(_PREHASH_Material,	material);

	U32 flags = 0;		// not selected
	if (use_physics)
	{
		flags |= FLAGS_USE_PHYSICS;
	}
//	if (create_selected)
// [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.0e) | Added: RLVa-1.0.0b
	if ( (create_selected) && (!gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) )
// [/RLVa:KB]
	{
		flags |= FLAGS_CREATE_SELECTED;
	}
	gMessageSystem->addU32Fast(_PREHASH_AddFlags, flags );

	LLPCode volume_pcode;	// ...PCODE_VOLUME, or the original on error
	switch (pcode)
	{
	case LL_PCODE_SPHERE:
		rotation.setQuat(90.f * DEG_TO_RAD, LLVector3::y_axis);

		volume_params.setType( LL_PCODE_PROFILE_CIRCLE_HALF, LL_PCODE_PATH_CIRCLE );
		volume_params.setBeginAndEndS( 0.f, 1.f );
		volume_params.setBeginAndEndT( 0.f, 1.f );
		volume_params.setRatio	( 1, 1 );
		volume_params.setShear	( 0, 0 );
		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
		volume_pcode = LL_PCODE_VOLUME;
		break;

	case LL_PCODE_TORUS:
		rotation.setQuat(90.f * DEG_TO_RAD, LLVector3::y_axis);

		volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_CIRCLE );
		volume_params.setBeginAndEndS( 0.f, 1.f );
		volume_params.setBeginAndEndT( 0.f, 1.f );
		volume_params.setRatio	( 1.f, 0.25f );	// "top size"
		volume_params.setShear	( 0, 0 );
		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
		volume_pcode = LL_PCODE_VOLUME;
		break;

	case LLViewerObject::LL_VO_SQUARE_TORUS:
		rotation.setQuat(90.f * DEG_TO_RAD, LLVector3::y_axis);

		volume_params.setType( LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_CIRCLE );
		volume_params.setBeginAndEndS( 0.f, 1.f );
		volume_params.setBeginAndEndT( 0.f, 1.f );
		volume_params.setRatio	( 1.f, 0.25f );	// "top size"
		volume_params.setShear	( 0, 0 );
		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
		volume_pcode = LL_PCODE_VOLUME;
		break;

	case LLViewerObject::LL_VO_TRIANGLE_TORUS:
		rotation.setQuat(90.f * DEG_TO_RAD, LLVector3::y_axis);

		volume_params.setType( LL_PCODE_PROFILE_EQUALTRI, LL_PCODE_PATH_CIRCLE );
		volume_params.setBeginAndEndS( 0.f, 1.f );
		volume_params.setBeginAndEndT( 0.f, 1.f );
		volume_params.setRatio	( 1.f, 0.25f );	// "top size"
		volume_params.setShear	( 0, 0 );
		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
		volume_pcode = LL_PCODE_VOLUME;
		break;

	case LL_PCODE_SPHERE_HEMI:
		volume_params.setType( LL_PCODE_PROFILE_CIRCLE_HALF, LL_PCODE_PATH_CIRCLE );
		//volume_params.setBeginAndEndS( 0.5f, 1.f );
		volume_params.setBeginAndEndT( 0.f, 0.5f );
		volume_params.setRatio	( 1, 1 );
		volume_params.setShear	( 0, 0 );
		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
		volume_pcode = LL_PCODE_VOLUME;
		break;

	case LL_PCODE_CUBE:
		volume_params.setType( LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE );
		volume_params.setBeginAndEndS( 0.f, 1.f );
		volume_params.setBeginAndEndT( 0.f, 1.f );
		volume_params.setRatio	( 1, 1 );
		volume_params.setShear	( 0, 0 );
		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
		volume_pcode = LL_PCODE_VOLUME;
		break;

	case LL_PCODE_PRISM:
		volume_params.setType( LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE );
		volume_params.setBeginAndEndS( 0.f, 1.f );
		volume_params.setBeginAndEndT( 0.f, 1.f );
		volume_params.setRatio	( 0, 1 );
		volume_params.setShear	( -0.5f, 0 );
		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
		volume_pcode = LL_PCODE_VOLUME;
		break;

	case LL_PCODE_PYRAMID:
		volume_params.setType( LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE );
		volume_params.setBeginAndEndS( 0.f, 1.f );
		volume_params.setBeginAndEndT( 0.f, 1.f );
		volume_params.setRatio	( 0, 0 );
		volume_params.setShear	( 0, 0 );
		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
		volume_pcode = LL_PCODE_VOLUME;
		break;

	case LL_PCODE_TETRAHEDRON:
		volume_params.setType( LL_PCODE_PROFILE_EQUALTRI, LL_PCODE_PATH_LINE );
		volume_params.setBeginAndEndS( 0.f, 1.f );
		volume_params.setBeginAndEndT( 0.f, 1.f );
		volume_params.setRatio	( 0, 0 );
		volume_params.setShear	( 0, 0 );
		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
		volume_pcode = LL_PCODE_VOLUME;
		break;

	case LL_PCODE_CYLINDER:
		volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE );
		volume_params.setBeginAndEndS( 0.f, 1.f );
		volume_params.setBeginAndEndT( 0.f, 1.f );
		volume_params.setRatio	( 1, 1 );
		volume_params.setShear	( 0, 0 );
		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
		volume_pcode = LL_PCODE_VOLUME;
		break;

	case LL_PCODE_CYLINDER_HEMI:
		volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE );
		volume_params.setBeginAndEndS( 0.25f, 0.75f );
		volume_params.setBeginAndEndT( 0.f, 1.f );
		volume_params.setRatio	( 1, 1 );
		volume_params.setShear	( 0, 0 );
		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
		volume_pcode = LL_PCODE_VOLUME;
		break;

	case LL_PCODE_CONE:
		volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE );
		volume_params.setBeginAndEndS( 0.f, 1.f );
		volume_params.setBeginAndEndT( 0.f, 1.f );
		volume_params.setRatio	( 0, 0 );
		volume_params.setShear	( 0, 0 );
		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
		volume_pcode = LL_PCODE_VOLUME;
		break;

	case LL_PCODE_CONE_HEMI:
		volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE );
		volume_params.setBeginAndEndS( 0.25f, 0.75f );
		volume_params.setBeginAndEndT( 0.f, 1.f );
		volume_params.setRatio	( 0, 0 );
		volume_params.setShear	( 0, 0 );
		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
		volume_pcode = LL_PCODE_VOLUME;
		break;

	default:
		LLVolumeMessage::packVolumeParams(0, gMessageSystem);
		volume_pcode = pcode;
		break;
	}
	gMessageSystem->addU8Fast(_PREHASH_PCode, volume_pcode);

	gMessageSystem->addVector3Fast(_PREHASH_Scale,			scale );
	gMessageSystem->addQuatFast(_PREHASH_Rotation,			rotation );
	gMessageSystem->addVector3Fast(_PREHASH_RayStart,		ray_start_region );
	gMessageSystem->addVector3Fast(_PREHASH_RayEnd,			ray_end_region );
	gMessageSystem->addU8Fast(_PREHASH_BypassRaycast,		(U8)b_hit_land );
	gMessageSystem->addU8Fast(_PREHASH_RayEndIsIntersection, (U8)FALSE );
	gMessageSystem->addU8Fast(_PREHASH_State, state);

	// Limit raycast to a single object.  
	// Speeds up server raycast + avoid problems with server ray hitting objects
	// that were clipped by the near plane or culled on the viewer.
	LLUUID ray_target_id;
	if( hit_obj )
	{
		ray_target_id = hit_obj->getID();
	}
	else
	{
		ray_target_id.setNull();
	}
	gMessageSystem->addUUIDFast(_PREHASH_RayTargetID,			ray_target_id );
	
	// Pack in name value pairs
	gMessageSystem->sendReliable(regionp->getHost());

	// Spawns a message, so must be after above send
	if (create_selected)
	{
		FSCommon::sObjectAddMsg++;
		LLSelectMgr::getInstance()->deselectAll();
		gViewerWindow->getWindow()->incBusyCount();
	}

	// VEFFECT: AddObject
	LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
	effectp->setSourceObject((LLViewerObject*)gAgentAvatarp);
	effectp->setPositionGlobal(regionp->getPosGlobalFromRegion(ray_end_region));
	effectp->setDuration(LL_HUD_DUR_SHORT);
	effectp->setColor(LLColor4U(gAgent.getEffectColor()));

	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CREATE_COUNT);

	return TRUE;
}
void LLSurfacePatch::calcNormal(const U32 x, const U32 y, const U32 stride)
{
	U32 patch_width = mSurfacep->mPVArray.mPatchWidth;
	U32 surface_stride = mSurfacep->getGridsPerEdge();

	const F32 mpg = mSurfacep->getMetersPerGrid() * stride;

	S32 poffsets[2][2][2];
	poffsets[0][0][0] = x - stride;
	poffsets[0][0][1] = y - stride;

	poffsets[0][1][0] = x - stride;
	poffsets[0][1][1] = y + stride;

	poffsets[1][0][0] = x + stride;
	poffsets[1][0][1] = y - stride;

	poffsets[1][1][0] = x + stride;
	poffsets[1][1][1] = y + stride;

	const LLSurfacePatch *ppatches[2][2];

	// LLVector3 p1, p2, p3, p4;

	ppatches[0][0] = this;
	ppatches[0][1] = this;
	ppatches[1][0] = this;
	ppatches[1][1] = this;

	U32 i, j;
	for (i = 0; i < 2; i++)
	{
		for (j = 0; j < 2; j++)
		{
			if (poffsets[i][j][0] < 0)
			{
				if (!ppatches[i][j]->getNeighborPatch(WEST))
				{
					poffsets[i][j][0] = 0;
				}
				else
				{
					poffsets[i][j][0] += patch_width;
					ppatches[i][j] = ppatches[i][j]->getNeighborPatch(WEST);
				}
			}
			if (poffsets[i][j][1] < 0)
			{
				if (!ppatches[i][j]->getNeighborPatch(SOUTH))
				{
					poffsets[i][j][1] = 0;
				}
				else
				{
					poffsets[i][j][1] += patch_width;
					ppatches[i][j] = ppatches[i][j]->getNeighborPatch(SOUTH);
				}
			}
			if (poffsets[i][j][0] >= (S32)patch_width)
			{
				if (!ppatches[i][j]->getNeighborPatch(EAST))
				{
					poffsets[i][j][0] = patch_width - 1;
				}
				else
				{
					poffsets[i][j][0] -= patch_width;
					ppatches[i][j] = ppatches[i][j]->getNeighborPatch(EAST);
				}
			}
			if (poffsets[i][j][1] >= (S32)patch_width)
			{
				if (!ppatches[i][j]->getNeighborPatch(NORTH))
				{
					poffsets[i][j][1] = patch_width - 1;
				}
				else
				{
					poffsets[i][j][1] -= patch_width;
					ppatches[i][j] = ppatches[i][j]->getNeighborPatch(NORTH);
				}
			}
		}
	}

	LLVector3 p00(-mpg,-mpg,
				  *(ppatches[0][0]->mDataZ
				  + poffsets[0][0][0]
				  + poffsets[0][0][1]*surface_stride));
	LLVector3 p01(-mpg,+mpg,
				  *(ppatches[0][1]->mDataZ
				  + poffsets[0][1][0]
				  + poffsets[0][1][1]*surface_stride));
	LLVector3 p10(+mpg,-mpg,
				  *(ppatches[1][0]->mDataZ
				  + poffsets[1][0][0]
				  + poffsets[1][0][1]*surface_stride));
	LLVector3 p11(+mpg,+mpg,
				  *(ppatches[1][1]->mDataZ
				  + poffsets[1][1][0]
				  + poffsets[1][1][1]*surface_stride));

	LLVector3 c1 = p11 - p00;
	LLVector3 c2 = p01 - p10;

	LLVector3 normal = c1;
	normal %= c2;
	normal.normVec();

	llassert(mDataNorm);
	*(mDataNorm + surface_stride * y + x) = normal;
}
Beispiel #29
0
LLVector3			LLVector3::scaledVec(const LLVector3& vec) const
{
	LLVector3 ret = LLVector3(*this);
	ret.scaleVec(vec);
	return ret;
}
Beispiel #30
0
//-----------------------------------------------------------------------------
// postBuild()
//-----------------------------------------------------------------------------
BOOL LLFloaterAnimPreview::postBuild()
{
	LLRect r;
	LLKeyframeMotion* motionp = NULL;
	LLBVHLoader* loaderp = NULL;

	if (!LLFloaterNameDesc::postBuild())
	{
		return FALSE;
	}

	childSetCommitCallback("name_form", onCommitName, this);

	childSetLabelArg("ok_btn", "[AMOUNT]", llformat("%d",sUploadAmount));
	childSetAction("ok_btn", onBtnOK, this);
	setDefaultBtn();

	mPreviewRect.set(PREVIEW_HPAD, 
		PREVIEW_TEXTURE_HEIGHT,
		getRect().getWidth() - PREVIEW_HPAD, 
		PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
	mPreviewImageRect.set(0.f, 1.f, 1.f, 0.f);

	S32 y = mPreviewRect.mTop + BTN_HEIGHT;
	S32 btn_left = PREVIEW_HPAD;

	r.set( btn_left, y, btn_left + 32, y - BTN_HEIGHT );
	mPlayButton = getChild<LLButton>( "play_btn");
	if (!mPlayButton)
	{
		mPlayButton = new LLButton(std::string("play_btn"), LLRect(0,0,0,0));
	}
	mPlayButton->setClickedCallback(onBtnPlay);
	mPlayButton->setCallbackUserData(this);

	mPlayButton->setImages(std::string("button_anim_play.tga"),
						   std::string("button_anim_play_selected.tga"));
	mPlayButton->setDisabledImages(LLStringUtil::null,LLStringUtil::null);

	mPlayButton->setScaleImage(TRUE);

	mStopButton = getChild<LLButton>( "stop_btn");
	if (!mStopButton)
	{
		mStopButton = new LLButton(std::string("stop_btn"), LLRect(0,0,0,0));
	}
	mStopButton->setClickedCallback(onBtnStop);
	mStopButton->setCallbackUserData(this);

	mStopButton->setImages(std::string("button_anim_stop.tga"),
						   std::string("button_anim_stop_selected.tga"));
	mStopButton->setDisabledImages(LLStringUtil::null,LLStringUtil::null);

	mStopButton->setScaleImage(TRUE);

	r.set(r.mRight + PREVIEW_HPAD, y, getRect().getWidth() - PREVIEW_HPAD, y - BTN_HEIGHT);
	//childSetCommitCallback("playback_slider", onSliderMove, this);

	childHide("bad_animation_text");

	//childSetCommitCallback("preview_base_anim", onCommitBaseAnim, this);
	//childSetValue("preview_base_anim", "Standing");

	//childSetCommitCallback("priority", onCommitPriority, this);
	//childSetCommitCallback("loop_check", onCommitLoop, this);
	//childSetCommitCallback("loop_in_point", onCommitLoopIn, this);
	//childSetValidate("loop_in_point", validateLoopIn);
	//childSetCommitCallback("loop_out_point", onCommitLoopOut, this);
	//childSetValidate("loop_out_point", validateLoopOut);

	//childSetCommitCallback("hand_pose_combo", onCommitHandPose, this);
	
	//childSetCommitCallback("emote_combo", onCommitEmote, this);
	//childSetValue("emote_combo", "[None]");

	//childSetCommitCallback("ease_in_time", onCommitEaseIn, this);
	//childSetValidate("ease_in_time", validateEaseIn);
	//childSetCommitCallback("ease_out_time", onCommitEaseOut, this);
	//childSetValidate("ease_out_time", validateEaseOut);

	std::string exten = gDirUtilp->getExtension(mFilename);
	if (exten == "bvh")
	{
		// loading a bvh file

		// now load bvh file
		S32 file_size;
		apr_file_t* fp = ll_apr_file_open(mFilenameAndPath, LL_APR_RB, &file_size);

		if (!fp)
		{
			llwarns << "Can't open BVH file:" << mFilename << llendl;	
		}
		else
		{
			char*	file_buffer;

			file_buffer = new char[file_size + 1];

			if (file_size == ll_apr_file_read(fp, file_buffer, file_size))
			{
				file_buffer[file_size] = '\0';
				llinfos << "Loading BVH file " << mFilename << llendl;
				loaderp = new LLBVHLoader(file_buffer);
			}

			apr_file_close(fp);
			delete[] file_buffer;
		}
	}

	if (loaderp && loaderp->isInitialized() && loaderp->getDuration() <= MAX_ANIM_DURATION)
	{
		// generate unique id for this motion
		mTransactionID.generate();
		mMotionID = mTransactionID.makeAssetID(gAgent.getSecureSessionID());

		mAnimPreview = new LLPreviewAnimation(256, 256);

		// motion will be returned, but it will be in a load-pending state, as this is a new motion
		// this motion will not request an asset transfer until next update, so we have a chance to 
		// load the keyframe data locally
		motionp = (LLKeyframeMotion*)mAnimPreview->getDummyAvatar()->createMotion(mMotionID);

		// create data buffer for keyframe initialization
		S32 buffer_size = loaderp->getOutputSize();
		U8* buffer = new U8[buffer_size];

		LLDataPackerBinaryBuffer dp(buffer, buffer_size);

		// pass animation data through memory buffer
		loaderp->serialize(dp);
		dp.reset();
		BOOL success = motionp && motionp->deserialize(dp);

		delete []buffer;

		if (success)
		{
			setAnimCallbacks() ;
			
			const LLBBoxLocal &pelvis_bbox = motionp->getPelvisBBox();

			LLVector3 temp = pelvis_bbox.getCenter();
			// only consider XY?
			//temp.mV[VZ] = 0.f;
			F32 pelvis_offset = temp.magVec();

			temp = pelvis_bbox.getExtent();
			//temp.mV[VZ] = 0.f;
			F32 pelvis_max_displacement = pelvis_offset + (temp.magVec() * 0.5f) + 1.f;
			
			F32 camera_zoom = LLViewerCamera::getInstance()->getDefaultFOV() / (2.f * atan(pelvis_max_displacement / PREVIEW_CAMERA_DISTANCE));
		
			mAnimPreview->setZoom(camera_zoom);

			motionp->setName(childGetValue("name_form").asString());
			mAnimPreview->getDummyAvatar()->startMotion(mMotionID);
			childSetMinValue("playback_slider", 0.0);
			childSetMaxValue("playback_slider", 1.0);

			childSetValue("loop_check", LLSD(motionp->getLoop()));
			childSetValue("loop_in_point", LLSD(motionp->getLoopIn() / motionp->getDuration() * 100.f));
			childSetValue("loop_out_point", LLSD(motionp->getLoopOut() / motionp->getDuration() * 100.f));
			childSetValue("priority", LLSD((F32)motionp->getPriority()));
			childSetValue("hand_pose_combo", LLHandMotion::getHandPoseName(motionp->getHandPose()));
			childSetValue("ease_in_time", LLSD(motionp->getEaseInDuration()));
			childSetValue("ease_out_time", LLSD(motionp->getEaseOutDuration()));
			setEnabled(TRUE);
			std::string seconds_string;
			seconds_string = llformat(" - %.2f seconds", motionp->getDuration());

			setTitle(mFilename + std::string(seconds_string));
		}
		else
		{
			delete mAnimPreview;
			mAnimPreview = NULL;
			mMotionID.setNull();
			childSetValue("bad_animation_text", getString("failed_to_initialize"));
		}
	}
	else
	{
		if ( loaderp )
		{
			if (loaderp->getDuration() > MAX_ANIM_DURATION)
			{
				LLUIString out_str = getString("anim_too_long");
				out_str.setArg("[LENGTH]", llformat("%.1f", loaderp->getDuration()));
				out_str.setArg("[MAX_LENGTH]", llformat("%.1f", MAX_ANIM_DURATION));
				childSetValue("bad_animation_text", out_str.getString());
			}
			else
			{
				LLUIString out_str = getString("failed_file_read");
				out_str.setArg("[STATUS]", loaderp->getStatus()); // *TODO:Translate
				childSetValue("bad_animation_text", out_str.getString());
			}
		}

		//setEnabled(FALSE);
		mMotionID.setNull();
		mAnimPreview = NULL;
	}

	refresh();

	delete loaderp;

	return TRUE;
}