void AFlarePlanetarium::BeginPlay() { Super::BeginPlay(); FLOG("AFlarePlanetarium::BeginPlay"); TArray<UActorComponent*> Components = GetComponentsByClass(UStaticMeshComponent::StaticClass()); for (int32 ComponentIndex = 0; ComponentIndex < Components.Num(); ComponentIndex++) { UStaticMeshComponent* PlanetCandidate = Cast<UStaticMeshComponent>(Components[ComponentIndex]); if (PlanetCandidate) { // Apply a new dynamic material to planets so that we can control shading parameters UMaterialInstanceConstant* BasePlanetMaterial = Cast<UMaterialInstanceConstant>(PlanetCandidate->GetMaterial(0)); if (BasePlanetMaterial) { //FLOGV("AFlarePlanetarium::BeginPlay : found planet '%s'", *PlanetCandidate->GetName()); #if PLATFORM_LINUX int32 UseNormalAsLightingDirection = 1; #else int32 UseNormalAsLightingDirection = 0; #endif UMaterialInstanceDynamic* PlanetMaterial = UMaterialInstanceDynamic::Create(BasePlanetMaterial, GetWorld()); PlanetCandidate->SetMaterial(0, PlanetMaterial); PlanetMaterial->SetScalarParameterValue("UseNormalAsLightingDirection", UseNormalAsLightingDirection); } } } }
void ABomb::ArmBomb() { if (bIsArmed) { //Chance the base color of the static mesh to red UMaterialInstanceDynamic* DynamicMAT = SM->CreateAndSetMaterialInstanceDynamic(0); DynamicMAT->SetVectorParameterValue(FName("Color"), FLinearColor::Red); } }
void USsPlayerComponent::SendRenderDynamicData_Concurrent() { if(NULL == SceneProxy) { return; } switch(RenderMode) { case ESsPlayerComponentRenderMode::Default: { const TArray<FSsRenderPart> RenderParts = Player.GetRenderParts(); TArray<FSsRenderPartWithMaterial> NewRenderParts; NewRenderParts.Reserve(RenderParts.Num()); for(int32 i = 0; i < RenderParts.Num(); ++i) { FSsRenderPartWithMaterial Part; FMemory::Memcpy(&Part, &(RenderParts[i]), sizeof(FSsRenderPart)); uint32 MatIdx = PartsMatIndex(Part.AlphaBlendType, Part.ColorBlendType); UMaterialInstanceDynamic** ppMID = PartsMIDMap[MatIdx].Find(Part.Texture); if(ppMID && *ppMID) { Part.Material = *ppMID; } else { UMaterialInstanceDynamic* NewMID = UMaterialInstanceDynamic::Create(BasePartsMaterials[MatIdx], this); if(NewMID) { NewMID->AddToRoot(); NewMID->SetFlags(RF_Transient); NewMID->SetTextureParameterValue(FName(TEXT("SsCellTexture")), Part.Texture); Part.Material = NewMID; PartsMIDMap[MatIdx].Add(Part.Texture, NewMID); } } NewRenderParts.Add(Part); } if(0 < NewRenderParts.Num()) { ENQUEUE_UNIQUE_RENDER_COMMAND_FOURPARAMETER( FSendSsPartsData, FSsRenderPartsProxy*, SsPartsProxy, (FSsRenderPartsProxy*)SceneProxy, TArray<FSsRenderPartWithMaterial>, InRenderParts, NewRenderParts, FVector2D, Pivot, Player.GetAnimPivot(), FVector2D, CanvasSizeUU, (Player.GetAnimCanvasSize() * UUPerPixel), { SsPartsProxy->CanvasSizeUU = CanvasSizeUU; SsPartsProxy->SetPivot(Pivot); SsPartsProxy->SetDynamicData_RenderThread(InRenderParts); }); }
void AShaderPluginDemoCharacter::OnFire() { //Try to set a texture to the object we hit! FHitResult HitResult; FVector StartLocation = FirstPersonCameraComponent->GetComponentLocation(); FRotator Direction = FirstPersonCameraComponent->GetComponentRotation(); FVector EndLocation = StartLocation + Direction.Vector() * 10000; FCollisionQueryParams QueryParams; QueryParams.AddIgnoredActor(this); if (GetWorld()->LineTraceSingleByChannel(HitResult, StartLocation, EndLocation, ECC_Visibility, QueryParams)) { TArray<UStaticMeshComponent*> StaticMeshComponents = TArray<UStaticMeshComponent*>(); AActor* HitActor = HitResult.GetActor(); if (NULL != HitActor) { HitActor->GetComponents<UStaticMeshComponent>(StaticMeshComponents); for (int32 i = 0; i < StaticMeshComponents.Num(); i++) { UStaticMeshComponent* CurrentStaticMeshPtr = StaticMeshComponents[i]; CurrentStaticMeshPtr->SetMaterial(0, MaterialToApplyToClickedObject); UMaterialInstanceDynamic* MID = CurrentStaticMeshPtr->CreateAndSetMaterialInstanceDynamic(0); UTexture* CastedRenderTarget = Cast<UTexture>(RenderTarget); MID->SetTextureParameterValue("InputTexture", CastedRenderTarget); } } } // try and play the sound if specified if (FireSound != NULL) { UGameplayStatics::PlaySoundAtLocation(this, FireSound, GetActorLocation()); } // try and play a firing animation if specified if (FireAnimation != NULL) { // Get the animation object for the arms mesh UAnimInstance* AnimInstance = Mesh1P->GetAnimInstance(); if (AnimInstance != NULL) { AnimInstance->Montage_Play(FireAnimation, 1.f); } } }
void AMurphysLawCharacter::ApplyMeshTeamColor() { // Put color on meshes if (ValidTeamBodyMeshColor && ValidTeamMaskMeshColor) { /* Get references to mesh material to be able to color them. */ UMaterialInstanceDynamic* ShaderMeshBody = GetMesh()->CreateDynamicMaterialInstance(0); UMaterialInstanceDynamic* ShaderMeshArms = GetMesh1P()->CreateDynamicMaterialInstance(0); checkf(ShaderMeshBody != nullptr && ShaderMeshArms != nullptr, TEXT("Unable to find first material on character")); ShaderMeshArms->SetVectorParameterValue(MATERIAL_PARAM_TEAM_COLOR_CLOTHES, TeamBodyMeshColor); ShaderMeshArms->SetVectorParameterValue(MATERIAL_PARAM_TEAM_COLOR_MASK, TeamMaskMeshColor); ShaderMeshBody->SetVectorParameterValue(MATERIAL_PARAM_TEAM_COLOR_CLOTHES, TeamBodyMeshColor); ShaderMeshBody->SetVectorParameterValue(MATERIAL_PARAM_TEAM_COLOR_MASK, TeamMaskMeshColor); } }
void FGridWidget::DrawNewGrid(const FSceneView* View, FPrimitiveDrawInterface* PDI) { if (LevelGridMaterial->IsCompilingOrHadCompileError(View->GetFeatureLevel()) || LevelGridMaterial2->IsCompilingOrHadCompileError(View->GetFeatureLevel())) { // The material would appear to be black (because we don't use a MaterialDomain but a UsageFlag - we should change that). // Here we rather want to hide it. return; } bool bUseTextureSolution = CVarEditorNewLevelGrid.GetValueOnGameThread() > 1; UMaterialInstanceDynamic *MaterialInst = bUseTextureSolution ? LevelGridMaterialInst2 : LevelGridMaterialInst; if(!MaterialInst) { return; } bool bMSAA = IsEditorCompositingMSAAEnabled(View->GetFeatureLevel()); bool bIsPerspective = ( View->ViewMatrices.ProjMatrix.M[3][3] < 1.0f ); // in unreal units float SnapGridSize = GEditor->GetGridSize(); // not used yet const bool bSnapEnabled = GetDefault<ULevelEditorViewportSettings>()->GridEnabled; float SnapAlphaMultiplier = 1.0f; // to get a light grid in a black level but use a high opacity value to be able to see it in a bright level static float Darken = 0.11f; static FName GridColorName("GridColor"); static FName SnapColorName("SnapColor"); static FName ExponentName("Exponent"); static FName AlphaBiasName("AlphaBias"); if(bIsPerspective) { MaterialInst->SetVectorParameterValue(GridColorName, FLinearColor(0.6f * Darken, 0.6f * Darken, 0.6f * Darken, CVarEditor3DGridFade.GetValueOnGameThread())); MaterialInst->SetVectorParameterValue(SnapColorName, FLinearColor(0.5f, 0.0f, 0.0f, SnapAlphaMultiplier * CVarEditor3DSnapFade.GetValueOnGameThread())); } else { MaterialInst->SetVectorParameterValue(GridColorName, FLinearColor(0.6f * Darken, 0.6f * Darken, 0.6f * Darken, CVarEditor2DGridFade.GetValueOnGameThread())); MaterialInst->SetVectorParameterValue(SnapColorName, FLinearColor(0.5f, 0.0f, 0.0f, SnapAlphaMultiplier * CVarEditor2DSnapFade.GetValueOnGameThread())); } // true:1m, false:1dm ios smallest grid size bool bLarger1mGrid = true; const int Exponent = 10; // 2 is the default so we need to set it MaterialInst->SetScalarParameterValue(ExponentName, (float)Exponent); // without MSAA we need the grid to be more see through so lines behind it can be recognized MaterialInst->SetScalarParameterValue(AlphaBiasName, bMSAA ? 0.0f : 0.05f); // grid for size float GridSplit = 0.5f; // red dots to visualize the snap float SnapSplit = 0.075f; float WorldToUVScale = 0.001f; if(bLarger1mGrid) { WorldToUVScale *= 0.1f; GridSplit *= 0.1f; } // in 2D all grid lines are same size in world space (they are at different scale so we need to adjust here) FLinearColor GridSplitTriple(GridSplit * 0.01f, GridSplit * 0.1f, GridSplit); if(bIsPerspective) { // largest grid lines GridSplitTriple.R *= 8.0f; // medium grid lines GridSplitTriple.G *= 3.0f; // fine grid lines GridSplitTriple.B *= 1.0f; } if(!bIsPerspective) { // screenspace size looks better in 2d float ScaleX = View->ViewMatrices.ProjMatrix.M[0][0] * View->ViewRect.Width(); float ScaleY = View->ViewMatrices.ProjMatrix.M[1][1] * View->ViewRect.Height(); float Scale = FMath::Min(ScaleX, ScaleY); float GridScale = CVarEditor2DSnapScale.GetValueOnGameThread(); float GridMin = CVarEditor2DSnapMin.GetValueOnGameThread(); // we need to account for a larger grids setting SnapSplit = 1.25f * FMath::Min(GridScale / SnapGridSize / Scale, GridMin); // hack test GridSplitTriple.R = 0.25f * FMath::Min(GridScale / 100 / Scale * 0.01f, GridMin); GridSplitTriple.G = 0.25f * FMath::Min(GridScale / 100 / Scale * 0.1f, GridMin); GridSplitTriple.B = 0.25f * FMath::Min(GridScale / 100 / Scale, GridMin); } float SnapTile = (1.0f / WorldToUVScale) / FMath::Max(1.0f, SnapGridSize); MaterialInst->SetVectorParameterValue("GridSplit", GridSplitTriple); MaterialInst->SetScalarParameterValue("SnapSplit", SnapSplit); MaterialInst->SetScalarParameterValue("SnapTile", SnapTile); FMatrix ObjectToWorld = FMatrix::Identity; FVector CameraPos = View->ViewMatrices.ViewOrigin; FVector2D UVCameraPos = FVector2D(CameraPos.X, CameraPos.Y); ObjectToWorld.SetOrigin(FVector(CameraPos.X, CameraPos.Y, 0)); FLinearColor AxisColors[3]; GetAxisColors(AxisColors, true); FLinearColor UAxisColor = AxisColors[1]; FLinearColor VAxisColor = AxisColors[0]; if(!bIsPerspective) { float FarZ = 100000.0f; if(View->ViewMatrices.ViewMatrix.M[1][1] == -1.f ) // Top { ObjectToWorld.SetOrigin(FVector(CameraPos.X, CameraPos.Y, -FarZ)); } if(View->ViewMatrices.ViewMatrix.M[1][2] == -1.f ) // Front { UVCameraPos = FVector2D(CameraPos.Z, CameraPos.X); ObjectToWorld.SetAxis(0, FVector(0,0,1)); ObjectToWorld.SetAxis(1, FVector(1,0,0)); ObjectToWorld.SetAxis(2, FVector(0,1,0)); ObjectToWorld.SetOrigin(FVector(CameraPos.X, -FarZ, CameraPos.Z)); UAxisColor = AxisColors[0]; VAxisColor = AxisColors[2]; } else if(View->ViewMatrices.ViewMatrix.M[1][0] == 1.f ) // Side { UVCameraPos = FVector2D(CameraPos.Y, CameraPos.Z); ObjectToWorld.SetAxis(0, FVector(0,1,0)); ObjectToWorld.SetAxis(1, FVector(0,0,1)); ObjectToWorld.SetAxis(2, FVector(1,0,0)); ObjectToWorld.SetOrigin(FVector(FarZ, CameraPos.Y, CameraPos.Z)); UAxisColor = AxisColors[2]; VAxisColor = AxisColors[1]; } } MaterialInst->SetVectorParameterValue("UAxisColor", UAxisColor); MaterialInst->SetVectorParameterValue("VAxisColor", VAxisColor); // We don't want to affect the mouse interaction. PDI->SetHitProxy(0); // good enough to avoid the AMD artifacts, horizon still appears to be a line float Radii = 100000; if(bIsPerspective) { // the higher we get the larger we make the geometry to give the illusion of an infinite grid while maintains the precision nearby Radii *= FMath::Max( 1.0f, FMath::Abs(CameraPos.Z) / 1000.0f ); } else { float ScaleX = View->ViewMatrices.ProjMatrix.M[0][0]; float ScaleY = View->ViewMatrices.ProjMatrix.M[1][1]; float Scale = FMath::Min(ScaleX, ScaleY); Scale *= View->ViewRect.Width(); // We render a larger grid if we are zoomed out more (good precision at any scale) Radii *= 1.0f / Scale; } FVector2D UVMid = UVCameraPos * WorldToUVScale; float UVRadi = Radii * WorldToUVScale; FVector2D UVMin = UVMid + FVector2D(-UVRadi, -UVRadi); FVector2D UVMax = UVMid + FVector2D(UVRadi, UVRadi); // vertex pos is in -1..1 range DrawPlane10x10(PDI, ObjectToWorld, Radii, UVMin, UVMax, MaterialInst->GetRenderProxy(false), SDPG_World ); }
int32 SSpineWidget::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const { SSpineWidget* self = (SSpineWidget*)this; if (widget && widget->skeleton && widget->Atlas) { widget->skeleton->getColor().set(widget->Color.R, widget->Color.G, widget->Color.B, widget->Color.A); if (widget->atlasNormalBlendMaterials.Num() != widget->Atlas->atlasPages.Num()) { widget->atlasNormalBlendMaterials.SetNum(0); widget->pageToNormalBlendMaterial.Empty(); widget->atlasAdditiveBlendMaterials.SetNum(0); widget->pageToAdditiveBlendMaterial.Empty(); widget->atlasMultiplyBlendMaterials.SetNum(0); widget->pageToMultiplyBlendMaterial.Empty(); widget->atlasScreenBlendMaterials.SetNum(0); widget->pageToScreenBlendMaterial.Empty(); for (int i = 0; i < widget->Atlas->atlasPages.Num(); i++) { AtlasPage* currPage = widget->Atlas->GetAtlas()->getPages()[i]; UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(widget->NormalBlendMaterial, widget); material->SetTextureParameterValue(widget->TextureParameterName, widget->Atlas->atlasPages[i]); widget->atlasNormalBlendMaterials.Add(material); widget->pageToNormalBlendMaterial.Add(currPage, material); material = UMaterialInstanceDynamic::Create(widget->AdditiveBlendMaterial, widget); material->SetTextureParameterValue(widget->TextureParameterName, widget->Atlas->atlasPages[i]); widget->atlasAdditiveBlendMaterials.Add(material); widget->pageToAdditiveBlendMaterial.Add(currPage, material); material = UMaterialInstanceDynamic::Create(widget->MultiplyBlendMaterial, widget); material->SetTextureParameterValue(widget->TextureParameterName, widget->Atlas->atlasPages[i]); widget->atlasMultiplyBlendMaterials.Add(material); widget->pageToMultiplyBlendMaterial.Add(currPage, material); material = UMaterialInstanceDynamic::Create(widget->ScreenBlendMaterial, widget); material->SetTextureParameterValue(widget->TextureParameterName, widget->Atlas->atlasPages[i]); widget->atlasScreenBlendMaterials.Add(material); widget->pageToScreenBlendMaterial.Add(currPage, material); } } else { widget->pageToNormalBlendMaterial.Empty(); widget->pageToAdditiveBlendMaterial.Empty(); widget->pageToMultiplyBlendMaterial.Empty(); widget->pageToScreenBlendMaterial.Empty(); for (int i = 0; i < widget->Atlas->atlasPages.Num(); i++) { AtlasPage* currPage = widget->Atlas->GetAtlas()->getPages()[i]; UTexture2D* texture = widget->Atlas->atlasPages[i]; UTexture* oldTexture = nullptr; UMaterialInstanceDynamic* current = widget->atlasNormalBlendMaterials[i]; if (!current || !current->GetTextureParameterValue(widget->TextureParameterName, oldTexture) || oldTexture != texture) { UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(widget->NormalBlendMaterial, widget); material->SetTextureParameterValue(widget->TextureParameterName, texture); widget->atlasNormalBlendMaterials[i] = material; } widget->pageToNormalBlendMaterial.Add(currPage, widget->atlasNormalBlendMaterials[i]); current = widget->atlasAdditiveBlendMaterials[i]; if (!current || !current->GetTextureParameterValue(widget->TextureParameterName, oldTexture) || oldTexture != texture) { UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(widget->AdditiveBlendMaterial, widget); material->SetTextureParameterValue(widget->TextureParameterName, texture); widget->atlasAdditiveBlendMaterials[i] = material; } widget->pageToAdditiveBlendMaterial.Add(currPage, widget->atlasAdditiveBlendMaterials[i]); current = widget->atlasMultiplyBlendMaterials[i]; if (!current || !current->GetTextureParameterValue(widget->TextureParameterName, oldTexture) || oldTexture != texture) { UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(widget->MultiplyBlendMaterial, widget); material->SetTextureParameterValue(widget->TextureParameterName, texture); widget->atlasMultiplyBlendMaterials[i] = material; } widget->pageToMultiplyBlendMaterial.Add(currPage, widget->atlasMultiplyBlendMaterials[i]); current = widget->atlasScreenBlendMaterials[i]; if (!current || !current->GetTextureParameterValue(widget->TextureParameterName, oldTexture) || oldTexture != texture) { UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(widget->ScreenBlendMaterial, widget); material->SetTextureParameterValue(widget->TextureParameterName, texture); widget->atlasScreenBlendMaterials[i] = material; } widget->pageToScreenBlendMaterial.Add(currPage, widget->atlasScreenBlendMaterials[i]); } } // self->UpdateMesh(LayerId, OutDrawElements, AllottedGeometry, widget->skeleton); } //return LayerId; self->renderData.IndexData.SetNumUninitialized(6); uint32* indexData = (uint32*)renderData.IndexData.GetData(); indexData[0] = 0; indexData[1] = 1; indexData[2] = 2; indexData[3] = 2; indexData[4] = 3; indexData[5] = 0; self->renderData.VertexData.SetNumUninitialized(4); FSlateVertex* vertexData = (FSlateVertex*)renderData.VertexData.GetData(); FVector2D offset = AllottedGeometry.AbsolutePosition; FColor white = FColor(0xffffffff); float width = AllottedGeometry.GetAbsoluteSize().X; float height = AllottedGeometry.GetAbsoluteSize().Y; setVertex(&vertexData[0], 0, 0, 0, 0, white, offset); setVertex(&vertexData[1], width, 0, 1, 0, white, offset); setVertex(&vertexData[2], width, height, 1, 1, white, offset); setVertex(&vertexData[3], 0, height, 0, 1, white, offset); if (brush && renderData.VertexData.Num() > 0 && renderData.IndexData.Num() > 0) { FSlateShaderResourceProxy* shaderResource = FSlateDataPayload::ResourceManager->GetShaderResource(widget->Brush); FSlateResourceHandle resourceHandle = FSlateApplication::Get().GetRenderer()->GetResourceHandle(widget->Brush); if (shaderResource) FSlateDrawElement::MakeCustomVerts(OutDrawElements, LayerId, resourceHandle, renderData.VertexData, renderData.IndexData, nullptr, 0, 0); } return LayerId; }
void AFlarePlanetarium::SetupCelestialBody(CelestialBodyPosition* BodyPosition, double DisplayDistance, double DisplayRadius) { FVector PlayerShipLocation = FVector::ZeroVector; if (GetGame()->GetPC()->GetShipPawn()) { PlayerShipLocation = GetGame()->GetPC()->GetShipPawn()->GetActorLocation(); } #ifdef PLANETARIUM_DEBUG DrawDebugSphere(GetWorld(), FVector::ZeroVector, DisplayDistance /1000 , 32, FColor::Blue, false); PlayerShipLocation = FVector::ZeroVector; DisplayRadius /= 1000; DisplayDistance /= 1000; #endif BodyPosition->BodyComponent->SetRelativeLocation((DisplayDistance * BodyPosition->AlignedLocation.GetUnsafeNormal()).ToVector() + PlayerShipLocation); float Scale = DisplayRadius / 512; // Mesh size is 1024; BodyPosition->BodyComponent->SetRelativeScale3D(FPreciseVector(Scale).ToVector()); FTransform BaseRotation = FTransform(FRotator(0, 0 ,90)); FTransform TimeRotation = FTransform(FRotator(0, BodyPosition->TotalRotation, 0)); FQuat Rotation = (TimeRotation * BaseRotation).GetRotation(); // TODO Rotation float time interpolation BodyPosition->BodyComponent->SetRelativeRotation(FQuat::Identity); BodyPosition->BodyComponent->SetRelativeRotation(Rotation); // Apply sun direction to component UMaterialInstanceDynamic* ComponentMaterial = Cast<UMaterialInstanceDynamic>(BodyPosition->BodyComponent->GetMaterial(0)); if (!ComponentMaterial) { ComponentMaterial = UMaterialInstanceDynamic::Create(BodyPosition->BodyComponent->GetMaterial(0) , GetWorld()); BodyPosition->BodyComponent->SetMaterial(0, ComponentMaterial); } ComponentMaterial->SetVectorParameterValue("SunDirection", SunDirection.ToVector()); // Look for rings and orient them TArray<USceneComponent*> RingCandidates; BodyPosition->BodyComponent->GetChildrenComponents(true, RingCandidates); for (int32 ComponentIndex = 0; ComponentIndex < RingCandidates.Num(); ComponentIndex++) { UStaticMeshComponent* RingComponent = Cast<UStaticMeshComponent>(RingCandidates[ComponentIndex]); if (RingComponent && RingComponent->GetName().Contains("ring")) { // Get or create the material UMaterialInstanceDynamic* RingMaterial = Cast<UMaterialInstanceDynamic>(RingComponent->GetMaterial(0)); if (!RingMaterial) { RingMaterial = UMaterialInstanceDynamic::Create(RingComponent->GetMaterial(0), GetWorld()); RingComponent->SetMaterial(0, RingMaterial); } // Get world-space rotation angles for the ring and the sun float SunRotationPitch = FMath::RadiansToDegrees(FMath::Atan2(SunDirection.Z,SunDirection.X)) + 180; float RingRotationPitch = -BodyPosition->TotalRotation; // Feed params to the shader RingMaterial->SetScalarParameterValue("RingPitch", RingRotationPitch / 360); RingMaterial->SetScalarParameterValue("SunPitch", SunRotationPitch / 360); } } // Sun also rotates to track direction if (BodyPosition->Body == &Sun) { BodyPosition->BodyComponent->SetRelativeRotation(SunDirection.ToVector().Rotation()); } // Compute sun occlusion if (BodyPosition->Body != &Sun) { double OcclusionAngle = FPreciseMath::Asin(BodyPosition->Radius / BodyPosition->Distance); float BodyPhase = FMath::UnwindRadians(FMath::Atan2(BodyPosition->AlignedLocation.Z, BodyPosition->AlignedLocation.X)); float CenterAngularDistance = FMath::Abs(FMath::UnwindRadians(SunPhase - BodyPhase)); float AngleSum = (SunOcclusionAngle + OcclusionAngle); float AngleDiff = FMath::Abs(SunOcclusionAngle - OcclusionAngle); /*FLOGV("SetupCelestialBody %s BodyPhase = %f", *BodyPosition->Body->Name.ToString(), FMath::RadiansToDegrees(BodyPhase)); FLOGV("SetupCelestialBody %s SunPhase = %f", *BodyPosition->Body->Name.ToString(), FMath::RadiansToDegrees(SunPhase)); FLOGV("SetupCelestialBody %s OcclusionAngle = %f", *BodyPosition->Body->Name.ToString(), FMath::RadiansToDegrees(OcclusionAngle)); FLOGV("SetupCelestialBody %s SunOcclusionAngle = %f", *BodyPosition->Body->Name.ToString(), FMath::RadiansToDegrees(SunOcclusionAngle)); FLOGV("SetupCelestialBody %s AngleDiff = %f", *BodyPosition->Body->Name.ToString(), FMath::RadiansToDegrees(AngleDiff)); FLOGV("SetupCelestialBody %s CenterAngularDistance = %f", *BodyPosition->Body->Name.ToString(), FMath::RadiansToDegrees(CenterAngularDistance)); FLOGV("SetupCelestialBody %s AngleSum = %f", *BodyPosition->Body->Name.ToString(), FMath::RadiansToDegrees(AngleSum));*/ if (CenterAngularDistance < AngleSum) { // There is occlusion float OcclusionRatio; if (CenterAngularDistance < AngleDiff) { // Maximum occlusion OcclusionRatio = 1.0; } else { // Partial occlusion OcclusionRatio = (AngleSum - CenterAngularDistance) / (2* FMath::Min(SunOcclusionAngle, OcclusionAngle)); // OcclusionRatio = ((SunOcclusionAngle + OcclusionAngle) + FMath::Max(SunOcclusionAngle, OcclusionAngle) - FMath::Min(SunOcclusionAngle, OcclusionAngle)) / (2 * CenterAngularDistance); } //FLOGV("MoveCelestialBody %s OcclusionRatio = %f", *Body->Name, OcclusionRatio); // Now, find the surface occlusion float SunAngularSurface = PI*FMath::Square(SunOcclusionAngle); float MaxOcclusionAngularSurface = PI*FMath::Square(FMath::Min(SunOcclusionAngle, OcclusionAngle)); float MaxOcclusion = MaxOcclusionAngularSurface / SunAngularSurface; float Occlusion = OcclusionRatio * MaxOcclusion; /*FLOGV("SetupCelestialBody %s CenterAngularDistance = %f", *BodyPosition->Body->Name.ToString(), CenterAngularDistance); FLOGV("SetupCelestialBody %s SunOcclusionAngle = %f", *BodyPosition->Body->Name.ToString(), SunOcclusionAngle); FLOGV("SetupCelestialBody %s OcclusionAngle = %f", *BodyPosition->Body->Name.ToString(), OcclusionAngle); FLOGV("SetupCelestialBody %s SunAngularSurface = %f", *BodyPosition->Body->Name.ToString(), SunAngularSurface); FLOGV("SetupCelestialBody %s MaxOcclusionAngularSurface = %f", *BodyPosition->Body->Name.ToString(), MaxOcclusionAngularSurface); FLOGV("SetupCelestialBody %s MaxOcclusion = %f", *BodyPosition->Body->Name.ToString(), MaxOcclusion); FLOGV("SetupCelestialBody %s Occlusion = %f", *BodyPosition->Body->Name.ToString(), Occlusion);*/ if (Occlusion > SunOcclusion) { // Keep only best occlusion SunOcclusion = Occlusion; } } } }
void USkeletalMeshComponent::TickAnimation(float DeltaTime) { SCOPE_CYCLE_COUNTER(STAT_AnimTickTime); if (SkeletalMesh != NULL) { if (AnimScriptInstance != NULL) { // Tick the animation AnimScriptInstance->UpdateAnimation(DeltaTime * GlobalAnimRateScale); // TODO @LinaH - I've hit access violations due to AnimScriptInstance being NULL after this, probably due to // AnimNotifies? Please take a look and fix as we discussed. Temporary fix: if (AnimScriptInstance != NULL) { // now all tick/trigger/kismet is done // add MorphTarget Curves from Kismet driven or any other source // and overwrite if it exists // Tick always should maintain this list, not Evaluate for( auto Iter = MorphTargetCurves.CreateConstIterator(); Iter; ++Iter ) { float *CurveValPtr = AnimScriptInstance->MorphTargetCurves.Find(Iter.Key()); if ( CurveValPtr ) { // override the value if Kismet request was made *CurveValPtr = Iter.Value(); } else { AnimScriptInstance->MorphTargetCurves.Add(Iter.Key(), Iter.Value()); } } //Update material parameters if(AnimScriptInstance->MaterialParameterCurves.Num() > 0) { for( auto Iter = AnimScriptInstance->MaterialParameterCurves.CreateConstIterator(); Iter; ++Iter ) { FName ParameterName = Iter.Key(); float ParameterValue = Iter.Value(); for(int32 MaterialIndex = 0; MaterialIndex < GetNumMaterials(); ++MaterialIndex) { UMaterialInterface* MaterialInterface = GetMaterial(MaterialIndex); if (MaterialInterface) { float TestValue; //not used but needed for GetScalarParameterValue call if(MaterialInterface->GetScalarParameterValue(ParameterName,TestValue)) { UMaterialInstanceDynamic* DynamicMaterial = Cast<UMaterialInstanceDynamic>(MaterialInterface); if(!DynamicMaterial) //Is it already a UMaterialInstanceDynamic (ie we used it last tick) { DynamicMaterial = CreateAndSetMaterialInstanceDynamic(MaterialIndex); } DynamicMaterial->SetScalarParameterValue(ParameterName, ParameterValue); //Assume that we only set the parameter on one of the materials, remove this break //if that is no longer desired break; } } } } } } } } }
UMaterialInstanceDynamic* UMaterialInstanceDynamic::Create(UMaterialInterface* ParentMaterial, UObject* InOuter) { UObject* Outer = InOuter ? InOuter : GetTransientPackage(); UMaterialInstanceDynamic* MID = NewObject<UMaterialInstanceDynamic>(Outer); MID->SetParentInternal(ParentMaterial, false); return MID; }