Пример #1
0
void LLNameValue::init(const char *name, const char *data, const char *type, const char *nvclass, const char *nvsendto)
{
	mNVNameTable = &gNVNameTable;

	mName = mNVNameTable->addString(name);
	
	// Nota Bene: Whatever global structure manages this should have these in the name table already!
	mStringType = mNVNameTable->addString(type);
	if (!strcmp(mStringType, "STRING"))
	{
		S32 string_length = (S32)strlen(data);		/*Flawfinder: Ignore*/
		mType = NVT_STRING;

		delete[] mNameValueReference.string;
		
		// two options here. . .  data can either look like foo or "foo"
		// WRONG! - this is a poorly implemented and incomplete escape
		// mechanism. For example, using this scheme, there is no way
		// to tell an intentional double quotes from a zero length
		// string. This needs to excised. Phoenix
		//if (strchr(data, '\"'))
		//{
		//	string_length -= 2;
		//	mNameValueReference.string = new char[string_length + 1];;
		//	strncpy(mNameValueReference.string, data + 1, string_length);
		//}
		//else
		//{
		mNameValueReference.string = new char[string_length + 1];;
		strncpy(mNameValueReference.string, data, string_length);		/*Flawfinder: Ignore*/
		//}
		mNameValueReference.string[string_length] = 0;
	}
	else if (!strcmp(mStringType, "F32"))
	{
		mType = NVT_F32;
		mNameValueReference.f32 = new F32((F32)atof(data));
	}
	else if (!strcmp(mStringType, "S32"))
	{
		mType = NVT_S32;
		mNameValueReference.s32 = new S32(atoi(data));
	}
	else if (!strcmp(mStringType, "U64"))
	{
		mType = NVT_U64;
		mNameValueReference.u64 = new U64(str_to_U64(ll_safe_string(data)));
	}
	else if (!strcmp(mStringType, "VEC3"))
	{
		mType = NVT_VEC3;
		F32 t1, t2, t3;

		// two options here. . .  data can either look like 0, 1, 2 or <0, 1, 2>

		if (strchr(data, '<'))
		{
			sscanf(data, "<%f, %f, %f>", &t1, &t2, &t3);
		}
		else
		{
			sscanf(data, "%f, %f, %f", &t1, &t2, &t3);
		}

		// finite checks
		if (!llfinite(t1) || !llfinite(t2) || !llfinite(t3))
		{
			t1 = 0.f;
			t2 = 0.f;
			t3 = 0.f;
		}

		mNameValueReference.vec3 = new LLVector3(t1, t2, t3);
	}
	else if (!strcmp(mStringType, "U32"))
	{
		mType = NVT_U32;
		mNameValueReference.u32 = new U32(atoi(data));
	}
	else if(!strcmp(mStringType, (const char*)NameValueTypeStrings[NVT_ASSET]))
	{
		// assets are treated like strings, except that the name has
		// meaning to an LLAssetInfo object
		S32 string_length = (S32)strlen(data);		/*Flawfinder: Ignore*/
		mType = NVT_ASSET;

		// two options here. . .  data can either look like foo or "foo"
		// WRONG! - this is a poorly implemented and incomplete escape
		// mechanism. For example, using this scheme, there is no way
		// to tell an intentional double quotes from a zero length
		// string. This needs to excised. Phoenix
		//if (strchr(data, '\"'))
		//{
		//	string_length -= 2;
		//	mNameValueReference.string = new char[string_length + 1];;
		//	strncpy(mNameValueReference.string, data + 1, string_length);
		//}
		//else
		//{
		mNameValueReference.string = new char[string_length + 1];;
		strncpy(mNameValueReference.string, data, string_length);		/*Flawfinder: Ignore*/
		//}
		mNameValueReference.string[string_length] = 0;
	}
	else
	{
		llwarns << "Unknown name value type string " << mStringType << " for " << mName << llendl;
		mType = NVT_NULL;
	}


	// Nota Bene: Whatever global structure manages this should have these in the name table already!
	if (!strcmp(nvclass, "R") ||
		!strcmp(nvclass, "READ_ONLY"))			// legacy
	{
		mClass = NVC_READ_ONLY;
		mStringClass = mNVNameTable->addString("R");
	}
	else if (!strcmp(nvclass, "RW") ||
			!strcmp(nvclass, "READ_WRITE"))	// legacy
	{
		mClass = NVC_READ_WRITE;
		mStringClass = mNVNameTable->addString("RW");
	}
	else
	{
		// assume it's bad
		mClass = NVC_NULL;
		mStringClass = mNVNameTable->addString(nvclass);
	}

	// Initialize the sendto variable
	if (!strcmp(nvsendto, "S") ||
		!strcmp(nvsendto, "SIM"))			// legacy
	{
		mSendto = NVS_SIM;
		mStringSendto = mNVNameTable->addString("S");
	}
	else if (!strcmp(nvsendto, "DS") ||
		!strcmp(nvsendto, "SIM_SPACE"))	// legacy
	{
		mSendto = NVS_DATA_SIM;
		mStringSendto = mNVNameTable->addString("DS");
	}
	else if (!strcmp(nvsendto, "SV") ||
			!strcmp(nvsendto, "SIM_VIEWER"))	// legacy
	{
		mSendto = NVS_SIM_VIEWER;
		mStringSendto = mNVNameTable->addString("SV");
	}
	else if (!strcmp(nvsendto, "DSV") ||
			!strcmp(nvsendto, "SIM_SPACE_VIEWER"))	// legacy
	{
		mSendto = NVS_DATA_SIM_VIEWER;
		mStringSendto = mNVNameTable->addString("DSV");
	}
	else
	{
		llwarns << "LLNameValue::init() - unknown sendto field " 
				<< nvsendto << " for NV " << mName << llendl;
		mSendto = NVS_NULL;
		mStringSendto = mNVNameTable->addString("S");
	}

}
Пример #2
0
BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)
{
	LLFastTimer ftm(FTM_UPDATE_PARTICLES);

	dirtySpatialGroup();
	
	S32 num_parts = mViewerPartGroupp->getCount();
	LLFace *facep;
	LLSpatialGroup* group = drawable->getSpatialGroup();
	if (!group && num_parts)
	{
		drawable->movePartition();
		group = drawable->getSpatialGroup();
	}

	if (group && group->isVisible())
	{
		dirtySpatialGroup(TRUE);
	}

	if (!num_parts)
	{
		if (group && drawable->getNumFaces())
		{
			group->setState(LLSpatialGroup::GEOM_DIRTY);
		}
		drawable->setNumFaces(0, NULL, getTEImage(0));
		return TRUE;
	}

 	if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES)))
	{
		return TRUE;
	}

	if (num_parts > drawable->getNumFaces())
	{
		drawable->setNumFacesFast(num_parts+num_parts/4, NULL, getTEImage(0));
	}

	F32 tot_area = 0;

	F32 max_area = LLViewerPartSim::getMaxPartCount() * MAX_PARTICLE_AREA_SCALE; 
	F32 pixel_meter_ratio = LLViewerCamera::getInstance()->getPixelMeterRatio();
	pixel_meter_ratio *= pixel_meter_ratio;

	LLViewerPartSim::checkParticleCount(mViewerPartGroupp->mParticles.size()) ;

	S32 count=0;
	mDepth = 0.f;
	S32 i = 0 ;
	LLVector3 camera_agent = getCameraPosition();
	
	F32 max_scale = 0.f;


	for (i = 0 ; i < (S32)mViewerPartGroupp->mParticles.size(); i++)
	{
		const LLViewerPart *part = mViewerPartGroupp->mParticles[i];


		//remember the largest particle
		max_scale = llmax(max_scale, part->mScale.mV[0], part->mScale.mV[1]);

		if (part->mFlags & LLPartData::LL_PART_RIBBON_MASK)
		{ //include ribbon segment length in scale
			const LLVector3* pos_agent = NULL;
			if (part->mParent)
			{
				pos_agent = &(part->mParent->mPosAgent);
			}
			else if (part->mPartSourcep.notNull())
			{
				pos_agent = &(part->mPartSourcep->mPosAgent);
			}

			if (pos_agent)
			{
				F32 dist = (*pos_agent-part->mPosAgent).length();

				max_scale = llmax(max_scale, dist);
			}
		}

		LLVector3 part_pos_agent(part->mPosAgent);
		LLVector3 at(part_pos_agent - camera_agent);

		
		F32 camera_dist_squared = at.lengthSquared();
		F32 inv_camera_dist_squared;
		if (camera_dist_squared > 1.f)
			inv_camera_dist_squared = 1.f / camera_dist_squared;
		else
			inv_camera_dist_squared = 1.f;

		llassert(llfinite(inv_camera_dist_squared));
		llassert(!llisnan(inv_camera_dist_squared));

		F32 area = part->mScale.mV[0] * part->mScale.mV[1] * inv_camera_dist_squared;
		tot_area = llmax(tot_area, area);
 		
		if (tot_area > max_area)
		{
			break;
		}
	
		count++;

		facep = drawable->getFace(i);
		if (!facep)
		{
			llwarns << "No face found for index " << i << "!" << llendl;
			continue;
		}

		facep->setTEOffset(i);
		const F32 NEAR_PART_DIST_SQ = 5.f*5.f;  // Only discard particles > 5 m from the camera
		const F32 MIN_PART_AREA = .005f*.005f;  // only less than 5 mm x 5 mm at 1 m from camera
		
		if (camera_dist_squared > NEAR_PART_DIST_SQ && area < MIN_PART_AREA)
		{
			facep->setSize(0, 0);
			continue;
		}

		facep->setSize(4, 6);
		
		facep->setViewerObject(this);

		if (part->mFlags & LLPartData::LL_PART_EMISSIVE_MASK)
		{
			facep->setState(LLFace::FULLBRIGHT);
		}
		else
		{
			facep->clearState(LLFace::FULLBRIGHT);
		}

		facep->mCenterLocal = part->mPosAgent;
		facep->setFaceColor(part->mColor);
		facep->setTexture(part->mImagep);
			
		//check if this particle texture is replaced by a parcel media texture.
		if(part->mImagep.notNull() && part->mImagep->hasParcelMedia()) 
		{
			part->mImagep->getParcelMedia()->addMediaToFace(facep) ;
		}

		mPixelArea = tot_area * pixel_meter_ratio;
		const F32 area_scale = 10.f; // scale area to increase priority a bit
		facep->setVirtualSize(mPixelArea*area_scale);
	}
	for (i = count; i < drawable->getNumFaces(); i++)
	{
		LLFace* facep = drawable->getFace(i);
		if (!facep)
		{
			llwarns << "No face found for index " << i << "!" << llendl;
			continue;
		}
		facep->setTEOffset(i);
		facep->setSize(0, 0);
	}

	//record max scale (used to stretch bounding box for visibility culling)
	
	mScale.set(max_scale, max_scale, max_scale);

	mDrawable->movePartition();
	return TRUE;
}
Пример #3
0
// Clamps length to an upper limit.  
// Returns TRUE if the data changed
BOOL LLVector3::clampLength( F32 length_limit )
{
	BOOL changed = FALSE;

	F32 len = length();
	if (llfinite(len))
	{
		if ( len > length_limit)
		{
			normalize();
			if (length_limit < 0.f)
			{
				length_limit = 0.f;
			}
			mV[0] *= length_limit;
			mV[1] *= length_limit;
			mV[2] *= length_limit;
			changed = TRUE;
		}
	}
	else
	{	// this vector may still be salvagable
		F32 max_abs_component = 0.f;
		for (S32 i = 0; i < 3; ++i)
		{
			F32 abs_component = fabs(mV[i]);
			if (llfinite(abs_component))
			{
				if (abs_component > max_abs_component)
				{
					max_abs_component = abs_component;
				}
			}
			else
			{
				// no it can't be salvaged --> clear it
				clear();
				changed = TRUE;
				break;
			}
		}
		if (!changed)
		{
			// yes it can be salvaged -->
			// bring the components down before we normalize
			mV[0] /= max_abs_component;
			mV[1] /= max_abs_component;
			mV[2] /= max_abs_component;
			normalize();

			if (length_limit < 0.f)
			{
				length_limit = 0.f;
			}
			mV[0] *= length_limit;
			mV[1] *= length_limit;
			mV[2] *= length_limit;
		}
	}

	return changed;
}