Ejemplo n.º 1
2
/** Generates valid X and Y axes of a coordinate system, given the Z axis. */
void GenerateCoordinateSystem(const FVector4& ZAxis, FVector4& XAxis, FVector4& YAxis)
{
	// Use the vector perpendicular to ZAxis and the Y axis as the XAxis
	const FVector4 XAxisCandidate = ZAxis ^ FVector4(0,1,0);
	if (XAxisCandidate.SizeSquared3() < KINDA_SMALL_NUMBER)
	{
		// The vector was nearly equal to the Y axis, use the X axis instead
		XAxis = (ZAxis ^ FVector4(1,0,0)).GetUnsafeNormal3();
	}
	else
	{
		XAxis = XAxisCandidate.GetUnsafeNormal3();
	}

	YAxis = ZAxis ^ XAxis;
	checkSlow(YAxis.IsUnit3());
}
Ejemplo n.º 2
0
	// from FStaticLightMesh....
	void FLandscapeStaticLightingMesh::GetStaticLightingVertex(int32 VertexIndex, FStaticLightingVertex& OutVertex) const
	{
		int32 X, Y;
		VertexIndexToXY(VertexIndex, X, Y);

		//GetWorldPositionTangents(X, Y, OutVertex.WorldPosition, OutVertex.WorldTangentX, OutVertex.WorldTangentY, OutVertex.WorldTangentZ);
		int32 LocalX = X-ExpandQuadsX;
		int32 LocalY = Y-ExpandQuadsY;

		const FColor* Data = GetHeightData( X, Y );

		OutVertex.WorldTangentZ.X = 2.f / 255.f * (float)Data->B - 1.f;
		OutVertex.WorldTangentZ.Y = 2.f / 255.f * (float)Data->A - 1.f;
		OutVertex.WorldTangentZ.Z = FMath::Sqrt(FMath::Max(1.f - (FMath::Square(OutVertex.WorldTangentZ.X)+FMath::Square(OutVertex.WorldTangentZ.Y)), 0.f));
		OutVertex.WorldTangentX = FVector4(OutVertex.WorldTangentZ.Z, 0.f, -OutVertex.WorldTangentZ.X);
		OutVertex.WorldTangentY = OutVertex.WorldTangentZ ^ OutVertex.WorldTangentX;

		// Assume there is no rotation, so we don't need to do any LocalToWorld.
		uint16 Height = (Data->R << 8) + Data->G;

		OutVertex.WorldPosition = LocalToWorld.TransformPosition( FVector4( LocalX, LocalY, ((float)Height - 32768.f) * LANDSCAPE_ZSCALE ) );
		//UE_LOG(LogLightmass, Log, TEXT("%d, %d, %d, %d, %d, %d, X:%f, Y:%f, Z:%f "), SectionBaseX+LocalX-ExpandQuadsX, SectionBaseY+LocalY-ExpandQuadsY, ClampedLocalX, ClampedLocalY, SectionBaseX, SectionBaseY, WorldPos.X, WorldPos.Y, WorldPos.Z);

		int32 LightmapUVIndex = 1;

		OutVertex.TextureCoordinates[0] = FVector2D((float)X / NumVertices, (float)Y / NumVertices); 
		OutVertex.TextureCoordinates[LightmapUVIndex].X = X * UVFactor;
		OutVertex.TextureCoordinates[LightmapUVIndex].Y = Y * UVFactor;
	}
Ejemplo n.º 3
0
	// from FStaticLightMesh....
	void FLandscapeStaticLightingMesh::GetStaticLightingVertex(int32 VertexIndex, FStaticLightingVertex& OutVertex) const
	{
		int32 X, Y;
		VertexIndexToXY(VertexIndex, X, Y);

		const int32 LocalX = X - ExpandQuadsX;
		const int32 LocalY = Y - ExpandQuadsY;

		const FColor* Data = GetHeightData( X, Y );

		OutVertex.WorldTangentZ.X = 2.0f / 255.f * (float)Data->B - 1.0f;
		OutVertex.WorldTangentZ.Y = 2.0f / 255.f * (float)Data->A - 1.0f;
		OutVertex.WorldTangentZ.Z = FMath::Sqrt(FMath::Max(1.0f - (FMath::Square(OutVertex.WorldTangentZ.X) + FMath::Square(OutVertex.WorldTangentZ.Y)), 0.f));
		OutVertex.WorldTangentX = FVector4(OutVertex.WorldTangentZ.Z, 0.0f, -OutVertex.WorldTangentZ.X);
		OutVertex.WorldTangentY = OutVertex.WorldTangentZ ^ OutVertex.WorldTangentX;

		// Copied (vaguely) from FLandscapeComponentDataInterface::GetWorldPositionTangents to fix bad lighting when rotated
		const FMatrix LtWNoScale = LocalToWorld.GetMatrixWithoutScale();
		OutVertex.WorldTangentX = LtWNoScale.TransformVector(OutVertex.WorldTangentX);
		OutVertex.WorldTangentY = LtWNoScale.TransformVector(OutVertex.WorldTangentY);
		OutVertex.WorldTangentZ = LtWNoScale.TransformVector(OutVertex.WorldTangentZ);

		const uint16 Height = (Data->R << 8) + Data->G;
		OutVertex.WorldPosition = LocalToWorld.TransformPosition( FVector4( LocalX, LocalY, ((float)Height - 32768.f) * LANDSCAPE_ZSCALE ) );
		//UE_LOG(LogLightmass, Log, TEXT("%d, %d, %d, %d, %d, %d, X:%f, Y:%f, Z:%f "), SectionBaseX + LocalX - ExpandQuadsX, SectionBaseY + LocalY - ExpandQuadsY, ClampedLocalX, ClampedLocalY, SectionBaseX, SectionBaseY, WorldPos.X, WorldPos.Y, WorldPos.Z);

		const int32 LightmapUVIndex = 1;

		OutVertex.TextureCoordinates[0] = FVector2D((float)X / NumVertices, (float)Y / NumVertices); 
		OutVertex.TextureCoordinates[LightmapUVIndex].X = X * UVFactor;
		OutVertex.TextureCoordinates[LightmapUVIndex].Y = Y * UVFactor;
	}
Ejemplo n.º 4
0
void FCanvasTriangleItem::Draw( class FCanvas* InCanvas )
{
	SCOPE_CYCLE_COUNTER(STAT_Canvas_TriItemTime);

	FBatchedElements* BatchedElements = InCanvas->GetBatchedElements(FCanvas::ET_Triangle, BatchedElementParameters, Texture, BlendMode);
	
	FHitProxyId HitProxyId = InCanvas->GetHitProxyId();

	for(int32 i=0; i<TriangleList.Num(); i++)
	{
		const FCanvasUVTri& Tri = TriangleList[i];
		int32 V0 = BatchedElements->AddVertex(FVector4(Tri.V0_Pos.X,Tri.V0_Pos.Y,0,1), Tri.V0_UV, Tri.V0_Color, HitProxyId);
		int32 V1 = BatchedElements->AddVertex(FVector4(Tri.V1_Pos.X,Tri.V1_Pos.Y,0,1), Tri.V1_UV, Tri.V1_Color, HitProxyId);
		int32 V2 = BatchedElements->AddVertex(FVector4(Tri.V2_Pos.X,Tri.V2_Pos.Y,0,1), Tri.V2_UV, Tri.V2_Color, HitProxyId);

		if( BatchedElementParameters )
		{
			BatchedElements->AddTriangle(V0,V1,V2, BatchedElementParameters, BlendMode);
		}
		else
		{
			check( Texture );
			BatchedElements->AddTriangle(V0,V1,V2,Texture, BlendMode);
		}
	}	
}
	virtual void SetMesh(FRHICommandList& RHICmdList, FShader* Shader,const FVertexFactory* VertexFactory,const FSceneView& View,const FMeshBatchElement& BatchElement,uint32 DataFlags) const override
	{
		const bool bInstanced = View.GetFeatureLevel() >= ERHIFeatureLevel::SM4;
		FMeshParticleVertexFactory* MeshParticleVF = (FMeshParticleVertexFactory*)VertexFactory;
		FVertexShaderRHIParamRef VertexShaderRHI = Shader->GetVertexShader();
		SetUniformBufferParameter(RHICmdList, VertexShaderRHI, Shader->GetUniformBufferParameter<FMeshParticleUniformParameters>(), MeshParticleVF->GetUniformBuffer() );

		if (!bInstanced)
		{
			const FMeshParticleVertexFactory::FBatchParametersCPU* BatchParameters = (const FMeshParticleVertexFactory::FBatchParametersCPU*)BatchElement.UserData;
			const FMeshParticleInstanceVertex* Vertex = BatchParameters->InstanceBuffer + BatchElement.UserIndex;
			const FMeshParticleInstanceVertexDynamicParameter* DynamicVertex = BatchParameters->DynamicParameterBuffer + BatchElement.UserIndex;

			SetShaderValue(RHICmdList, VertexShaderRHI, Transform1, Vertex->Transform[0]);
			SetShaderValue(RHICmdList, VertexShaderRHI, Transform2, Vertex->Transform[1]);
			SetShaderValue(RHICmdList, VertexShaderRHI, Transform3, Vertex->Transform[2]);
			SetShaderValue(RHICmdList, VertexShaderRHI, SubUVParams, FVector4((float)Vertex->SubUVParams[0], (float)Vertex->SubUVParams[1], (float)Vertex->SubUVParams[2], (float)Vertex->SubUVParams[3]));
			SetShaderValue(RHICmdList, VertexShaderRHI, SubUVLerp, Vertex->SubUVLerp);
			SetShaderValue(RHICmdList, VertexShaderRHI, ParticleDirection, Vertex->Velocity);
			SetShaderValue(RHICmdList, VertexShaderRHI, RelativeTime, Vertex->RelativeTime);
			if (BatchParameters->DynamicParameterBuffer)
			{
				SetShaderValue(RHICmdList, VertexShaderRHI, DynamicParameter, FVector4(DynamicVertex->DynamicValue[0], DynamicVertex->DynamicValue[1], DynamicVertex->DynamicValue[2], DynamicVertex->DynamicValue[3]));
			}
			SetShaderValue(RHICmdList, VertexShaderRHI, ParticleColor, FVector4(Vertex->Color.Component(0), Vertex->Color.Component(1), Vertex->Color.Component(2), Vertex->Color.Component(3)));
		}
	}
	virtual void InitRHI() override
	{
		FRHIResourceCreateInfo CreateInfo;
		VertexBufferRHI = RHICreateVertexBuffer(sizeof(FVector4) * 2, BUF_Static, CreateInfo);
		FVector4* DummyContents = (FVector4*)RHILockVertexBuffer(VertexBufferRHI,0,sizeof(FVector4)*2,RLM_WriteOnly);
		DummyContents[0] = FVector4(0.0f, 0.0f, 0.0f, 0.0f);
		DummyContents[1] = FVector4(1.0f, 1.0f, 1.0f, 1.0f);
		RHIUnlockVertexBuffer(VertexBufferRHI);
	}
void FNiagaraSimulation::Tick(float DeltaSeconds)
{
	SCOPE_CYCLE_COUNTER(STAT_NiagaraTick);
	SimpleTimer TickTime;

	UNiagaraEmitterProperties* PinnedProps = Props.Get();
	if (!PinnedProps || !bIsEnabled || TickState == NTS_Suspended || TickState == NTS_Dead)
	{
		return;
	}

	Age += DeltaSeconds;

	check(Data.GetNumVariables() > 0);
	check(PinnedProps->SpawnScriptProps.Script);
	check(PinnedProps->UpdateScriptProps.Script);
	
	TickEvents(DeltaSeconds);

	// Figure out how many we will spawn.
	int32 OrigNumParticles = Data.GetNumInstances();
	int32 NumToSpawn = CalcNumToSpawn(DeltaSeconds);
	int32 MaxNewParticles = OrigNumParticles + NumToSpawn;
	Data.Allocate(MaxNewParticles);

	ExternalConstants.SetOrAdd(BUILTIN_CONST_EMITTERAGE, FVector4(Age, Age, Age, Age));
	ExternalConstants.SetOrAdd(BUILTIN_CONST_DELTATIME, FVector4(DeltaSeconds, DeltaSeconds, DeltaSeconds, DeltaSeconds));

	// Simulate particles forward by DeltaSeconds.
	if (TickState==NTS_Running || TickState==NTS_Dieing)
	{
		SCOPE_CYCLE_COUNTER(STAT_NiagaraSimulate);
		RunVMScript(PinnedProps->UpdateScriptProps, EUnusedAttributeBehaviour::PassThrough);
	}

	//Init new particles with the spawn script.
	if (TickState==NTS_Running)
	{
		SCOPE_CYCLE_COUNTER(STAT_NiagaraSpawn);
		Data.SetNumInstances(MaxNewParticles);
		//For now, zero any unused attributes here. But as this is really uninitialized data we should maybe make this a more serious error.
		RunVMScript(PinnedProps->SpawnScriptProps, EUnusedAttributeBehaviour::Zero, OrigNumParticles, NumToSpawn);

		if (bGenerateSpawnEvents)
		{
			SpawnEventGenerator.OnSpawned(OrigNumParticles, NumToSpawn);
		}
	}


	CPUTimeMS = TickTime.GetElapsedMilliseconds();

	INC_DWORD_STAT_BY(STAT_NiagaraNumParticles, Data.GetNumInstances());
}
Ejemplo n.º 8
0
bool FWindSourceSceneProxy::GetDirectionalWindParameters(FVector4& WindDirectionAndSpeed, float& Weight) const 
{ 
	if (bIsPointSource)
	{
		Weight = 0.f;
		WindDirectionAndSpeed = FVector4(0,0,0,0);
		return false;
	}

	Weight = Strength;
	WindDirectionAndSpeed = FVector4(Direction * Strength, Speed); 
	return true;
}
Ejemplo n.º 9
0
	/** Initialization constructor. */
	explicit FNiagaraCompilerContext(FCompilerResultsLog& InLog)
		: Log(InLog)
	{
		ConstantNames.Add(TEXT("__zero__"));
		Constants.Add(FVector4(0.0f, 0.0f, 0.0f, 0.0f));

		// Setup built-in constants.
		for (uint32 i = 0; i < NiagaraConstants::NumBuiltinConstants; i++)
		{
			ConstantNames.Add(NiagaraConstants::ConstantNames[i]);
			Constants.Add(FVector4(0.0f, 0.0f, 0.0f, 0.0f));
		}
	}
Ejemplo n.º 10
0
void FSceneView::DeprojectScreenToWorld(const FVector2D& ScreenPos, const FIntRect& ViewRect, const FMatrix& InvViewMatrix, const FMatrix& InvProjectionMatrix, FVector& out_WorldOrigin, FVector& out_WorldDirection)
{
	int32 PixelX = FMath::TruncToInt(ScreenPos.X);
	int32 PixelY = FMath::TruncToInt(ScreenPos.Y);

	// Get the eye position and direction of the mouse cursor in two stages (inverse transform projection, then inverse transform view).
	// This avoids the numerical instability that occurs when a view matrix with large translation is composed with a projection matrix

	// Get the pixel coordinates into 0..1 normalized coordinates within the constrained view rectangle
	const float NormalizedX = (PixelX - ViewRect.Min.X) / ((float)ViewRect.Width());
	const float NormalizedY = (PixelY - ViewRect.Min.Y) / ((float)ViewRect.Height());

	// Get the pixel coordinates into -1..1 projection space
	const float ScreenSpaceX = (NormalizedX - 0.5f) * 2.0f;
	const float ScreenSpaceY = ((1.0f - NormalizedY) - 0.5f) * 2.0f;

	// The start of the raytrace is defined to be at mousex,mousey,1 in projection space (z=1 is near, z=0 is far - this gives us better precision)
	// To get the direction of the raytrace we need to use any z between the near and the far plane, so let's use (mousex, mousey, 0.5)
	const FVector4 RayStartProjectionSpace = FVector4(ScreenSpaceX, ScreenSpaceY, 1.0f, 1.0f);
	const FVector4 RayEndProjectionSpace = FVector4(ScreenSpaceX, ScreenSpaceY, 0.5f, 1.0f);

	// Projection (changing the W coordinate) is not handled by the FMatrix transforms that work with vectors, so multiplications
	// by the projection matrix should use homogeneous coordinates (i.e. FPlane).
	const FVector4 HGRayStartViewSpace = InvProjectionMatrix.TransformFVector4(RayStartProjectionSpace);
	const FVector4 HGRayEndViewSpace = InvProjectionMatrix.TransformFVector4(RayEndProjectionSpace);
	FVector RayStartViewSpace(HGRayStartViewSpace.X, HGRayStartViewSpace.Y, HGRayStartViewSpace.Z);
	FVector RayEndViewSpace(HGRayEndViewSpace.X,   HGRayEndViewSpace.Y,   HGRayEndViewSpace.Z);
	// divide vectors by W to undo any projection and get the 3-space coordinate 
	if (HGRayStartViewSpace.W != 0.0f)
	{
		RayStartViewSpace /= HGRayStartViewSpace.W;
	}
	if (HGRayEndViewSpace.W != 0.0f)
	{
		RayEndViewSpace /= HGRayEndViewSpace.W;
	}
	FVector RayDirViewSpace = RayEndViewSpace - RayStartViewSpace;
	RayDirViewSpace = RayDirViewSpace.GetSafeNormal();

	// The view transform does not have projection, so we can use the standard functions that deal with vectors and normals (normals
	// are vectors that do not use the translational part of a rotation/translation)
	const FVector RayStartWorldSpace = InvViewMatrix.TransformPosition(RayStartViewSpace);
	const FVector RayDirWorldSpace = InvViewMatrix.TransformVector(RayDirViewSpace);

	// Finally, store the results in the hitcheck inputs.  The start position is the eye, and the end position
	// is the eye plus a long distance in the direction the mouse is pointing.
	out_WorldOrigin = RayStartWorldSpace;
	out_WorldDirection = RayDirWorldSpace.GetSafeNormal();
}
Ejemplo n.º 11
0
void FSceneRenderer::InitFogConstants()
{
	// console command override
	float FogDensityOverride = -1.0f;
	float FogStartDistanceOverride = -1.0f;

#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
	{
		// console variable overrides
		FogDensityOverride = CVarFogDensity.GetValueOnAnyThread();
		FogStartDistanceOverride = CVarFogStartDistance.GetValueOnAnyThread();
	}
#endif // !(UE_BUILD_SHIPPING || UE_BUILD_TEST)

	for(int32 ViewIndex = 0;ViewIndex < Views.Num();ViewIndex++)
	{
		FViewInfo& View = Views[ViewIndex];
		// set fog consts based on height fog components
		if(ShouldRenderFog(*View.Family))
		{
			if (Scene->ExponentialFogs.Num() > 0)
			{
				const FExponentialHeightFogSceneInfo& FogInfo = Scene->ExponentialFogs[0];
				const float CosTerminatorAngle = FMath::Clamp(FMath::Cos(FogInfo.LightTerminatorAngle * PI / 180.0f), -1.0f + DELTA, 1.0f - DELTA);
				const float CollapsedFogParameterPower = FMath::Clamp(
						-FogInfo.FogHeightFalloff * (View.ViewMatrices.ViewOrigin.Z - FogInfo.FogHeight),
						-126.f + 1.f, // min and max exponent values for IEEE floating points (http://en.wikipedia.org/wiki/IEEE_floating_point)
						+127.f - 1.f
						);
				const float CollapsedFogParameter = FogInfo.FogDensity * FMath::Pow(2.0f, CollapsedFogParameterPower);
				View.ExponentialFogParameters = FVector4(CollapsedFogParameter, FogInfo.FogHeightFalloff, CosTerminatorAngle, FogInfo.StartDistance);
				View.ExponentialFogColor = FVector(FogInfo.FogColor.R, FogInfo.FogColor.G, FogInfo.FogColor.B);
				View.FogMaxOpacity = FogInfo.FogMaxOpacity;

				View.DirectionalInscatteringExponent = FogInfo.DirectionalInscatteringExponent;
				View.DirectionalInscatteringStartDistance = FogInfo.DirectionalInscatteringStartDistance;
				View.bUseDirectionalInscattering = false;
				View.InscatteringLightDirection = FVector(0);

				for (TSparseArray<FLightSceneInfoCompact>::TConstIterator It(Scene->Lights); It; ++It)
				{
					const FLightSceneInfoCompact& LightInfo = *It;

					// This will find the first directional light that is set to be used as an atmospheric sun light of sufficient brightness.
					// If you have more than one directional light with these properties then all subsequent lights will be ignored.
					if (LightInfo.LightSceneInfo->Proxy->GetLightType() == LightType_Directional
						&& LightInfo.LightSceneInfo->Proxy->IsUsedAsAtmosphereSunLight()
						&& LightInfo.LightSceneInfo->Proxy->GetColor().ComputeLuminance() > KINDA_SMALL_NUMBER
						&& FogInfo.DirectionalInscatteringColor.ComputeLuminance() > KINDA_SMALL_NUMBER)
					{
						View.InscatteringLightDirection = -LightInfo.LightSceneInfo->Proxy->GetDirection();
						View.bUseDirectionalInscattering = true;
						View.DirectionalInscatteringColor = FogInfo.DirectionalInscatteringColor * LightInfo.LightSceneInfo->Proxy->GetColor().ComputeLuminance();
						break;
					}
				}
			}
		}
	}
}
Ejemplo n.º 12
0
void FIndirectLightingCache::UpdateTransitionsOverTime(const TArray<FIndirectLightingCacheAllocation*>& TransitionsOverTimeToUpdate, float DeltaWorldTime) const
{
	for (int32 AllocationIndex = 0; AllocationIndex < TransitionsOverTimeToUpdate.Num(); AllocationIndex++)
	{
		FIndirectLightingCacheAllocation* Allocation = TransitionsOverTimeToUpdate[AllocationIndex];
		const float TransitionDistance = (Allocation->SingleSamplePosition - Allocation->TargetPosition).Size();

		if (TransitionDistance > DELTA)
		{
			// Compute a frame rate independent transition by maintaining a constant world space speed between the current sample position and the target position
			const float LerpFactor = FMath::Clamp(GSingleSampleTransitionSpeed * DeltaWorldTime / TransitionDistance, 0.0f, 1.0f);
			Allocation->SingleSamplePosition = FMath::Lerp(Allocation->SingleSamplePosition, Allocation->TargetPosition, LerpFactor);

			for (int32 VectorIndex = 0; VectorIndex < ARRAY_COUNT(Allocation->SingleSamplePacked); VectorIndex++)
			{
				Allocation->SingleSamplePacked[VectorIndex] = FMath::Lerp(Allocation->SingleSamplePacked[VectorIndex], Allocation->TargetSamplePacked[VectorIndex], LerpFactor);
			}

			Allocation->CurrentDirectionalShadowing = FMath::Lerp(Allocation->CurrentDirectionalShadowing, Allocation->TargetDirectionalShadowing, LerpFactor);

			const FVector CurrentSkyBentNormal = FMath::Lerp(
				FVector(Allocation->CurrentSkyBentNormal) * Allocation->CurrentSkyBentNormal.W, 
				FVector(Allocation->TargetSkyBentNormal) * Allocation->TargetSkyBentNormal.W, 
				LerpFactor);

			const float BentNormalLength = CurrentSkyBentNormal.Size();

			Allocation->CurrentSkyBentNormal = FVector4(CurrentSkyBentNormal / FMath::Max(BentNormalLength, .0001f), BentNormalLength);
		}
	}
}
void FPixelShaderUsageExample::ExecutePixelShader(UTextureRenderTarget2D* RenderTarget, FTexture2DRHIRef InputTexture, FColor EndColor, float TextureParameterBlendFactor)
{
	check(IsInGameThread());

	if (bIsUnloading || bIsPixelShaderExecuting) //Skip this execution round if we are already executing
		return;

	if (!RenderTarget)
		return;

	bIsPixelShaderExecuting = true;

	if (TextureParameter != InputTexture)
		bMustRegenerateSRV = true;

	//Now set our runtime parameters!
	VariableParameters.EndColor = FVector4(EndColor.R / 255.0, EndColor.G / 255.0, EndColor.B / 255.0, EndColor.A / 255.0);
	VariableParameters.TextureParameterBlendFactor = TextureParameterBlendFactor;

	CurrentRenderTarget = RenderTarget;
	TextureParameter = InputTexture;

	//This macro sends the function we declare inside to be run on the render thread. What we do is essentially just send this class and tell the render thread to run the internal render function as soon as it can.
	//I am still not 100% Certain on the thread safety of this, if you are getting crashes, depending on how advanced code you have in the start of the ExecutePixelShader function, you might have to use a lock :)
	ENQUEUE_UNIQUE_RENDER_COMMAND_ONEPARAMETER(
		FPixelShaderRunner,
		FPixelShaderUsageExample*, PixelShader, this,
		{
			PixelShader->ExecutePixelShaderInternal();
		}
Ejemplo n.º 14
0
void FShadowMap2D::Serialize(FArchive& Ar)
{
	FShadowMap::Serialize(Ar);
	
	if( Ar.IsCooking() && !Ar.CookingTarget()->SupportsFeature(ETargetPlatformFeatures::DistanceFieldShadows) )
	{
		UShadowMapTexture2D* Dummy = NULL;
		Ar << Dummy;
	}
	else
	{
		Ar << Texture;
	}

	Ar << CoordinateScale << CoordinateBias;

	for (int Channel = 0; Channel < ARRAY_COUNT(bChannelValid); Channel++)
	{
		Ar << bChannelValid[Channel];
	}

	if (Ar.UE4Ver() >= VER_UE4_STATIC_SHADOWMAP_PENUMBRA_SIZE)
	{
		Ar << InvUniformPenumbraSize;
	}
	else if (Ar.IsLoading())
	{
		const float LegacyValue = 1.0f / .05f;
		InvUniformPenumbraSize = FVector4(LegacyValue, LegacyValue, LegacyValue, LegacyValue);
	}
}
Ejemplo n.º 15
0
// Render onto tt (using renderer) sitting @ cameraPos,
// facing cameraDir, an object with radiusWorldUnits.
void ATheHUD::RenderScreen( USceneCaptureComponent2D* renderer, FVector lookPos, float radiusWorldUnits, FVector cameraDir )
{
  UTextureRenderTarget2D* tt = renderer->TextureTarget;
  // http://stackoverflow.com/questions/3717226/
  // radiusOnScreenPX = radiusWorldUnits*SW/(tan(fov / 2) * Z);
  // ZBack = radiusWorldUnits*SW/(tan( fovy / 2 )*radiusOnScreenPX)
  // Calculate Z distance back for a given pixel radius
  // Set particular render properties & render the screen
  // to texture in w.
  float D = GetZDistance( radiusWorldUnits, tt->GetSurfaceWidth(), tt->GetSurfaceHeight(), renderer->FOVAngle );
  FVector eyePos = lookPos - cameraDir * D;
  FQuat quat = cameraDir.Rotation().Quaternion();
  renderer->SetRelativeLocationAndRotation( eyePos, quat );
  
  FVector2D screenSize = ui->gameChrome->gameCanvas->Size;
  screenSize.X -= ui->gameChrome->rightPanel->Size.X;

  FVector up = renderer->GetUpVector();
  FLookAtMatrix lookAt( eyePos, lookPos, up );
  FPerspectiveMatrix persp( rendererMinimap->FOVAngle/2.f, 1.f, 1.f, 0.5f );
  FMatrix mvp1 = lookAt * persp;

  vector<Ray> rays = Game->pc->GetFrustumRays( FBox2DU( 0.f, 0.f, screenSize.X, screenSize.Y ) );
  float zValue = lookPos.Z;
  FPlane plane( FVector(0.f, 0.f, 1.f), zValue );
  vector<FVector> pts;
  for( int i = 0; i < rays.size(); i++ )
  {
    FVector pt = FMath::LinePlaneIntersection( rays[i].start, rays[i].end, plane );
    //Game->flycam->DrawDebug( pt, 25.f, FLinearColor::White, .25f );
    pts.push_back( pt );
  }

  //FLinearColor Cyan(0,1,1,1);
  //for( int i = 0; i < pts.size() - 1; i++ )
  //{
  //  Game->flycam->DrawDebug( pts[i], pts[i+1], 25.f, Cyan, .25f );
  //}
  //if( pts.size() > 1 )
  //{
  //  Game->flycam->DrawDebug( pts[pts.size()-1], pts[0], 25.f, Cyan, .25f );
  //}

  ui->gameChrome->rightPanel->minimap->pts.clear();
  FVector2D minimapSize = ui->gameChrome->rightPanel->minimap->Size;
  for( int i = 0; i < pts.size(); i++ )
  {
    FVector4 transformedPt = mvp1.TransformPosition( pts[i] );
    float div = transformedPt.W;
    transformedPt /= FVector4( div, div, div, div );
    FVector2D p( transformedPt.X, transformedPt.Y ); // between [-1,1]
    p *= 4.f/3.f; //!! Multiplying P by 4./3 req'd.. double-check
    p *= minimapSize/2.f;
    p.Y *= -1.f;
    p += minimapSize/2.f;

    p += ui->gameChrome->rightPanel->minimap->GetAbsPos();
    ui->gameChrome->rightPanel->minimap->pts.push_back( p );
  }
}
Ejemplo n.º 16
0
UTexture::UTexture(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	SRGB = true;
	Filter = TF_Default;
#if WITH_EDITORONLY_DATA
	AdjustBrightness = 1.0f;
	AdjustBrightnessCurve = 1.0f;
	AdjustVibrance = 0.0f;
	AdjustSaturation = 1.0f;
	AdjustRGBCurve = 1.0f;
	AdjustHue = 0.0f;
	AdjustMinAlpha = 0.0f;
	AdjustMaxAlpha = 1.0f;
	MaxTextureSize = 0; // means no limitation
	MipGenSettings = TMGS_FromTextureGroup;
	CompositeTextureMode = CTM_NormalRoughnessToAlpha;
	CompositePower = 1.0f;
	bUseLegacyGamma = false;
	AlphaCoverageThresholds = FVector4(0, 0, 0, 0);
	PaddingColor = FColor::Black;
	ChromaKeyColor = FColorList::Magenta;
	ChromaKeyThreshold = 1.0f / 255.0f;
	
#endif // #if WITH_EDITORONLY_DATA

	if (FApp::CanEverRender() && !IsTemplate())
	{
		TextureReference.BeginInit_GameThread();
	}
}
	void SetParameters(const FRenderingCompositePassContext& Context)
	{
		const FPixelShaderRHIParamRef ShaderRHI = GetPixelShader();

		FGlobalShader::SetParameters(ShaderRHI, Context.View);

		PostprocessParameter.SetPS(ShaderRHI, Context, TStaticSamplerState<SF_Point,AM_Clamp,AM_Clamp,AM_Clamp>::GetRHI());

		{
			const float SizeX = Context.View.ViewRect.Width();
			const float SizeY = Context.View.ViewRect.Height();
			const float InvAspectRatio = SizeY / SizeX;

			const FSceneViewState* ViewState = (FSceneViewState*) Context.View.State;
			const float MotionBlurTimeScale = ViewState ? ViewState->MotionBlurTimeScale : 1.0f;

			const float ViewMotionBlurScale = 0.5f * MotionBlurTimeScale * Context.View.FinalPostProcessSettings.MotionBlurAmount;

			// 0:no 1:full screen width
			float MaxVelocity = Context.View.FinalPostProcessSettings.MotionBlurMax / 100.0f;
			float InvMaxVelocity = 1.0f / MaxVelocity;
			float ObjectScaleX = ViewMotionBlurScale * InvMaxVelocity;
			float ObjectScaleY = ViewMotionBlurScale * InvMaxVelocity * InvAspectRatio;

			SetShaderValue( ShaderRHI, VelocityScale, FVector4( ObjectScaleX, -ObjectScaleY, 0, 0 ) );
		}
	}
Ejemplo n.º 18
0
	void SetParameters(const FRenderingCompositePassContext& Context, IPooledRenderTarget& DistortionRT)
	{
		const FPixelShaderRHIParamRef ShaderRHI = GetPixelShader();

		FTextureRHIParamRef DistortionTextureValue = DistortionRT.GetRenderTargetItem().ShaderResourceTexture;
		FTextureRHIParamRef SceneColorTextureValue = GSceneRenderTargets.GetSceneColor()->GetRenderTargetItem().ShaderResourceTexture;

		// Here we use SF_Point as in fullscreen the pixels are 1:1 mapped.
		SetTextureParameter(
			Context.RHICmdList,
			ShaderRHI,
			DistortionTexture,
			DistortionTextureSampler,
			TStaticSamplerState<SF_Point,AM_Clamp,AM_Clamp,AM_Clamp>::GetRHI(),
			DistortionTextureValue
			);

		SetTextureParameter(
			Context.RHICmdList,
			ShaderRHI,
			SceneColorTexture,
			SceneColorTextureSampler,
			TStaticSamplerState<SF_Bilinear,AM_Clamp,AM_Clamp,AM_Clamp>::GetRHI(),
			SceneColorTextureValue
			);

		FIntPoint SceneBufferSize = GSceneRenderTargets.GetBufferSizeXY();
		FIntRect ViewportRect = Context.GetViewport();
		FVector4 SceneColorRectValue = FVector4((float)ViewportRect.Min.X/SceneBufferSize.X,
												(float)ViewportRect.Min.Y/SceneBufferSize.Y,
												(float)ViewportRect.Max.X/SceneBufferSize.X,
												(float)ViewportRect.Max.Y/SceneBufferSize.Y);
		SetShaderValue(Context.RHICmdList, ShaderRHI, SceneColorRect, SceneColorRectValue);
	}
Ejemplo n.º 19
0
	/**
	* Initialize the RHI for this rendering resource
	*/
	void InitRHI() override
	{
		const int32 NumVerts = 8;
		TResourceArray<FVector4, VERTEXBUFFER_ALIGNMENT> Verts;
		Verts.SetNumUninitialized(NumVerts);

		for (uint32 Z = 0; Z < 2; Z++)
		{
			for (uint32 Y = 0; Y < 2; Y++)
			{
				for (uint32 X = 0; X < 2; X++)
				{
					const FVector4 Vertex = FVector4(
					  (X ? -1 : 1),
					  (Y ? -1 : 1),
					  (Z ? -1 : 1),
					  1.0f
					);

					Verts[GetCubeVertexIndex(X, Y, Z)] = Vertex;
				}
			}
		}

		uint32 Size = Verts.GetResourceDataSize();

		// Create vertex buffer. Fill buffer with initial data upon creation
		FRHIResourceCreateInfo CreateInfo(&Verts);
		VertexBufferRHI = RHICreateVertexBuffer(Size, BUF_Static, CreateInfo);
	}
Ejemplo n.º 20
0
void UMaterialParameterCollectionInstance::GetParameterData(TArray<FVector4>& ParameterData) const
{
	// The memory layout created here must match the index assignment in UMaterialParameterCollection::GetParameterIndex

	if (Collection)
	{
		ParameterData.Empty(FMath::DivideAndRoundUp(Collection->ScalarParameters.Num(), 4) + Collection->VectorParameters.Num());

		for (int32 ParameterIndex = 0; ParameterIndex < Collection->ScalarParameters.Num(); ParameterIndex++)
		{
			const FCollectionScalarParameter& Parameter = Collection->ScalarParameters[ParameterIndex];

			// Add a new vector for each packed vector
			if (ParameterIndex % 4 == 0)
			{
				ParameterData.Add(FVector4(0, 0, 0, 0));
			}

			FVector4& CurrentVector = ParameterData.Last();
			const float* InstanceData = ScalarParameterValues.Find(Parameter.ParameterName);
			// Pack into the appropriate component of this packed vector
			CurrentVector[ParameterIndex % 4] = InstanceData ? *InstanceData : Parameter.DefaultValue;
		}

		for (int32 ParameterIndex = 0; ParameterIndex < Collection->VectorParameters.Num(); ParameterIndex++)
		{
			const FCollectionVectorParameter& Parameter = Collection->VectorParameters[ParameterIndex];
			const FLinearColor* InstanceData = VectorParameterValues.Find(Parameter.ParameterName);
			ParameterData.Add(InstanceData ? *InstanceData : Parameter.DefaultValue);
		}
	}
}
void FIndirectLightingCache::UpdateTransitionsOverTime(const TArray<FIndirectLightingCacheAllocation*>& TransitionsOverTimeToUpdate, float DeltaWorldTime) const
{
	for (int32 AllocationIndex = 0; AllocationIndex < TransitionsOverTimeToUpdate.Num(); AllocationIndex++)
	{
		FIndirectLightingCacheAllocation* Allocation = TransitionsOverTimeToUpdate[AllocationIndex];
		const float TransitionDistance = (Allocation->SingleSamplePosition - Allocation->TargetPosition).Size();

		if (TransitionDistance > DELTA)
		{
			// Transition faster for unbuilt meshes which is important for meshing visualization
			const float EffectiveTransitionSpeed = GSingleSampleTransitionSpeed * (Allocation->bUnbuiltPreview ? 4 : 1);
			const float LerpFactor = FMath::Clamp(GSingleSampleTransitionSpeed * DeltaWorldTime / TransitionDistance, 0.0f, 1.0f);
			Allocation->SingleSamplePosition = FMath::Lerp(Allocation->SingleSamplePosition, Allocation->TargetPosition, LerpFactor);

			for (int32 VectorIndex = 0; VectorIndex < 3; VectorIndex++) // RGB
			{
				Allocation->SingleSamplePacked0[VectorIndex] = FMath::Lerp(Allocation->SingleSamplePacked0[VectorIndex], Allocation->TargetSamplePacked0[VectorIndex], LerpFactor);
				Allocation->SingleSamplePacked1[VectorIndex] = FMath::Lerp(Allocation->SingleSamplePacked1[VectorIndex], Allocation->TargetSamplePacked1[VectorIndex], LerpFactor);
			}
			Allocation->SingleSamplePacked2 = FMath::Lerp(Allocation->SingleSamplePacked2, Allocation->TargetSamplePacked2, LerpFactor);
			Allocation->CurrentDirectionalShadowing = FMath::Lerp(Allocation->CurrentDirectionalShadowing, Allocation->TargetDirectionalShadowing, LerpFactor);

			const FVector CurrentSkyBentNormal = FMath::Lerp(
				FVector(Allocation->CurrentSkyBentNormal) * Allocation->CurrentSkyBentNormal.W, 
				FVector(Allocation->TargetSkyBentNormal) * Allocation->TargetSkyBentNormal.W, 
				LerpFactor);

			const float BentNormalLength = CurrentSkyBentNormal.Size();

			Allocation->CurrentSkyBentNormal = FVector4(CurrentSkyBentNormal / FMath::Max(BentNormalLength, .0001f), BentNormalLength);
		}
	}
}
Ejemplo n.º 22
0
	void SetParameters(FRHICommandList& RHICmdList, const FViewInfo& View)
	{
		FGlobalShader::SetParameters(RHICmdList, GetVertexShader(),View);

		{
			// The fog can be set to start at a certain euclidean distance.
			// clamp the value to be behind the near plane z
			float FogStartDistance = FMath::Max(30.0f, View.ExponentialFogParameters.W);

			// Here we compute the nearest z value the fog can start
			// to render the quad at this z value with depth test enabled.
			// This means with a bigger distance specified more pixels are
			// are culled and don't need to be rendered. This is faster if
			// there is opaque content nearer than the computed z.

			FMatrix InvProjectionMatrix = View.ViewMatrices.GetInvProjMatrix();

			FVector ViewSpaceCorner = InvProjectionMatrix.TransformFVector4(FVector4(1, 1, 1, 1));

			float Ratio = ViewSpaceCorner.Z / ViewSpaceCorner.Size();

			FVector ViewSpaceStartFogPoint(0.0f, 0.0f, FogStartDistance * Ratio);
			FVector4 ClipSpaceMaxDistance = View.ViewMatrices.ProjMatrix.TransformPosition(ViewSpaceStartFogPoint);

			float FogClipSpaceZ = ClipSpaceMaxDistance.Z / ClipSpaceMaxDistance.W;

			SetShaderValue(RHICmdList, GetVertexShader(),FogStartZ, FogClipSpaceZ);
		}
	}
TOptional<FVector4> FVectorPropertySection::GetPropertyValueAsVector4() const
{
	if (ChannelsUsed == 2)
	{
		TOptional<FVector2D> Vector = GetPropertyValue<FVector2D>();
		return Vector.IsSet() ? TOptional<FVector4>(FVector4(Vector.GetValue().X, Vector.GetValue().Y, 0, 0)) : TOptional<FVector4>();
	}
	else if (ChannelsUsed == 3)
	{
		TOptional<FVector> Vector = GetPropertyValue<FVector>();
		return Vector.IsSet() ? TOptional<FVector4>(FVector4(Vector.GetValue().X, Vector.GetValue().Y, Vector.GetValue().Z, 0)) : TOptional<FVector4>();
	}
	else // ChannelsUsed == 4
	{
		return GetPropertyValue<FVector4>();
	}
}
Ejemplo n.º 24
0
FVector4 UniformSampleHemisphere(float Uniform1, float Uniform2)
{
	const float R = FMath::Sqrt(1.0f - Uniform1 * Uniform1);
	const float Phi = 2.0f * (float)PI * Uniform2;

	// Convert to Cartesian
	return FVector4(FMath::Cos(Phi) * R, FMath::Sin(Phi) * R, Uniform1);
}
FVector4 UMovieSceneVectorSection::Eval( float Position, const FVector4& DefaultVector ) const
{
	return FVector4(
		Curves[0].Eval( Position, DefaultVector.X ),
		Curves[1].Eval( Position, DefaultVector.Y ),
		Curves[2].Eval( Position, DefaultVector.Z ),
		Curves[3].Eval( Position, DefaultVector.W ) );
}
FVector4 UMovieSceneVectorSection::Eval( float Position ) const
{
    return FVector4(
               Curves[0].Eval( Position ),
               Curves[1].Eval( Position ),
               Curves[2].Eval( Position ),
               Curves[3].Eval( Position ) );
}
Ejemplo n.º 27
0
/** 
 * Generates a pseudo-random unit vector in the Z > 0 hemisphere,
 * Whose PDF == (SpecularPower + 1) / (2.0f * PI) * cos(Alpha) ^ SpecularPower in solid angles,
 * Where Alpha is the angle between the perfect specular direction and the outgoing direction.
 */
FVector4 GetModifiedPhongSpecularVector(FLMRandomStream& RandomStream, const FVector4& TangentSpecularDirection, float SpecularPower)
{
	checkSlow(TangentSpecularDirection.Z >= 0.0f);
	checkSlow(SpecularPower > 0.0f);

	FVector4 GeneratedTangentVector;
	do
	{
		// Generate hemispherical coordinates in the local frame of the perfect specular direction
		// Don't allow a value of 0, since that results in a PDF of 0 with large specular powers due to floating point imprecision
		const float Alpha = FMath::Min(FMath::Acos(FMath::Pow(FMath::Max(RandomStream.GetFraction(), DELTA), 1.0f / (SpecularPower + 1.0f))), (float)HALF_PI - DELTA);
		const float Phi = 2.0f * (float)PI * RandomStream.GetFraction();
		
		// Convert to Cartesian, still in the coordinate space of the perfect specular direction
		const float SinTheta = FMath::Sin(Alpha);
		const FVector4 GeneratedSpecularTangentVector(FMath::Cos(Phi) * SinTheta, FMath::Sin(Phi) * SinTheta, FMath::Cos(Alpha));

		// Generate the X and Y axes of the coordinate space whose Z is the perfect specular direction
		FVector4 SpecularTangentX = (TangentSpecularDirection ^ FVector4(0,1,0)).GetUnsafeNormal3();
		if (SpecularTangentX.SizeSquared3() < KINDA_SMALL_NUMBER)
		{
			// The specular direction was nearly equal to the Y axis, use the X axis instead
			SpecularTangentX = (TangentSpecularDirection ^ FVector4(1,0,0)).GetUnsafeNormal3();
		}
		else
		{
			SpecularTangentX = SpecularTangentX.GetUnsafeNormal3();
		}
		const FVector4 SpecularTangentY = TangentSpecularDirection ^ SpecularTangentX;

		// Rotate the generated coordinates into the local frame of the tangent space normal (0,0,1)
		const FVector4 SpecularTangentRow0(SpecularTangentX.X, SpecularTangentY.X, TangentSpecularDirection.X);
		const FVector4 SpecularTangentRow1(SpecularTangentX.Y, SpecularTangentY.Y, TangentSpecularDirection.Y);
		const FVector4 SpecularTangentRow2(SpecularTangentX.Z, SpecularTangentY.Z, TangentSpecularDirection.Z);
		GeneratedTangentVector = FVector4(
			Dot3(SpecularTangentRow0, GeneratedSpecularTangentVector),
			Dot3(SpecularTangentRow1, GeneratedSpecularTangentVector),
			Dot3(SpecularTangentRow2, GeneratedSpecularTangentVector)
			);
	}
	// Regenerate an Alpha as long as the direction is outside of the tangent space Z > 0 hemisphere, 
	// Since some part of the cosine lobe around the specular direction can be outside of the hemisphere around the surface normal.
	while (GeneratedTangentVector.Z < DELTA);
	return GeneratedTangentVector;
}
Ejemplo n.º 28
0
/**
 * Computes scale and bias to apply in order to sample the curve. The value
 * should be used as TexCoord.xy = Curve.xy + Curve.zw * t.
 * @param TexelAllocation - The texel allocation in the texture.
 * @returns the scale and bias needed to sample the curve.
 */
FVector4 FParticleCurveTexture::ComputeCurveScaleBias( FTexelAllocation TexelAllocation )
{
	return FVector4(
		((float)TexelAllocation.X + 0.5f) / (float)GParticleCurveTextureSizeX,
		((float)TexelAllocation.Y + 0.5f) / (float)GParticleCurveTextureSizeY,
		(float)(TexelAllocation.Size - 1) / (float)GParticleCurveTextureSizeX,
		TexelAllocation.Size > 0 ? 0.0f : 1.0f
		);
}
Ejemplo n.º 29
0
	/** Accesses parameters needed for rendering the light. */
	virtual void GetParameters(FVector4& LightPositionAndInvRadius, FVector4& LightColorAndFalloffExponent, FVector& NormalizedLightDirection, FVector2D& SpotAngles, float& LightSourceRadius, float& LightSourceLength, float& LightMinRoughness) const override
	{
		LightPositionAndInvRadius = FVector4(
			GetOrigin(),
			InvRadius);

		LightColorAndFalloffExponent = FVector4(
			GetColor().R,
			GetColor().G,
			GetColor().B,
			FalloffExponent);

		NormalizedLightDirection = -GetDirection();
		SpotAngles = FVector2D(CosOuterCone, InvCosConeDifference);
		LightSourceRadius = SourceRadius;
		LightSourceLength = SourceLength;
		LightMinRoughness = MinRoughness;
	}
void UNiagaraNodeWriteDataSet::Compile(class INiagaraCompiler* Compiler, TArray<FNiagaraNodeResult>& Outputs)
{
	bool bError = false;

	if (DataSet.Type == ENiagaraDataSetType::Event)
	{
		//Compile the Emit pin.
		TNiagaraExprPtr EmitExpression = Compiler->CompilePin(Pins[0]);

		if (EmitExpression.IsValid())
		{
			//Test the Valid pin result against 0. Maybe just require a direct connection of 0 or 0xFFFFFFFF?
			FNiagaraVariableInfo Zero(TEXT("0.0, 0.0, 0.0, 0.0"), ENiagaraDataType::Vector);
			TNiagaraExprPtr ZeroContantExpression = Compiler->GetInternalConstant(Zero, FVector4(0.0f, 0.0f, 0.0f, 0.0f));
			TArray<TNiagaraExprPtr> ConditonInputs;
			ConditonInputs.Add(EmitExpression);
			ConditonInputs.Add(ZeroContantExpression);
			check(ZeroContantExpression.IsValid());
			TArray<TNiagaraExprPtr> ConditionOpOutputs;
			INiagaraCompiler::GreaterThan(Compiler, ConditonInputs, ConditionOpOutputs);
			TNiagaraExprPtr ValidExpr = ConditionOpOutputs[0];

			TArray<TNiagaraExprPtr> InputExpressions;
			for (int32 i = 0; i < Variables.Num(); ++i)
			{
				const FNiagaraVariableInfo& Var = Variables[i];
				UEdGraphPin* Pin = Pins[i + 1];//Pin[0] is emit
				check(Pin->Direction == EGPD_Input);

				TNiagaraExprPtr Result = Compiler->CompilePin(Pin);
				if (!Result.IsValid())
				{
					bError = true;
					Compiler->Error(FText::Format(LOCTEXT("DataSetWriteErrorFormat", "Error writing variable {0} to dataset {1}"), FText::FromName(DataSet.Name), Pin->PinFriendlyName), this, Pin);
				}

				InputExpressions.Add(Result);
			}

			//Gets the index to write to. 
			TNiagaraExprPtr IndexExpression = Compiler->AcquireSharedDataIndex(DataSet, true, ValidExpr);

			if (!bError)
			{
				check(Variables.Num() == InputExpressions.Num());
				for (int32 i = 0; i < Variables.Num(); ++i)
				{
					Outputs.Add(FNiagaraNodeResult(Compiler->SharedDataWrite(DataSet, Variables[i], IndexExpression, InputExpressions[i]), Pins[i + 1]));//Pin[0] is Emit
				}
			}
		}
	}
	else
	{
		check(false);//IMPLEMENT OTHER DATA SETS.
	}
}