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 USCarryObjectComponent::Throw() { if (!GetIsCarryingActor()) return; if (GetOwner()->Role < ROLE_Authority) { ServerThrow(); return; } /* Grab a reference to the MeshComp before dropping the object */ UStaticMeshComponent* MeshComp = GetCarriedMeshComp(); if (MeshComp) { /* Detach and re-enable collision */ OnDropMulticast(); APawn* OwningPawn = Cast<APawn>(GetOwner()); if (OwningPawn) { /* Re-map uint8 to 360 degrees */ const float PawnViewPitch = (OwningPawn->RemoteViewPitch / 255.f)*360.f; FRotator NewRotation = GetComponentRotation(); NewRotation.Pitch = PawnViewPitch; /* Apply physics impulse, ignores mass */ MeshComp->AddImpulse(NewRotation.Vector() * 1000, NAME_None, true); } } }
FThumbnailPreviewScene::FThumbnailPreviewScene() : FPreviewScene( ConstructionValues() .SetLightRotation( FRotator(304.736, 39.84, 0) ) .SetCreatePhysicsScene(false) .SetTransactional(false)) { // A background sky sphere UStaticMeshComponent* BackgroundComponent = NewObject<UStaticMeshComponent>(); BackgroundComponent->SetStaticMesh( GUnrealEd->GetThumbnailManager()->EditorSkySphere ); const float SkySphereScale = 2000.0f; const FTransform BackgroundTransform(FRotator(0,0,0), FVector(0,0,0), FVector(SkySphereScale)); FPreviewScene::AddComponent(BackgroundComponent, BackgroundTransform); // Adjust the default light DirectionalLight->Intensity = 0.2f; // Add additional lights UDirectionalLightComponent* DirectionalLight2 = NewObject<UDirectionalLightComponent>(); DirectionalLight->Intensity = 5.0f; AddComponent(DirectionalLight2, FTransform( FRotator(-40,-144.678, 0) )); UDirectionalLightComponent* DirectionalLight3 = NewObject<UDirectionalLightComponent>(); DirectionalLight->Intensity = 1.0f; AddComponent(DirectionalLight3, FTransform( FRotator(299.235,144.993, 0) )); // Add an infinite plane const float FloorPlaneScale = 10000.f; const FTransform FloorPlaneTransform(FRotator(-90.f,0,0), FVector::ZeroVector, FVector(FloorPlaneScale)); UStaticMeshComponent* FloorPlaneComponent = NewObject<UStaticMeshComponent>(); FloorPlaneComponent->SetStaticMesh( GUnrealEd->GetThumbnailManager()->EditorPlane ); FloorPlaneComponent->SetMaterial( 0, GUnrealEd->GetThumbnailManager()->FloorPlaneMaterial ); FPreviewScene::AddComponent(FloorPlaneComponent, FloorPlaneTransform); }
AActor* USCarryObjectComponent::GetActorInView() { APawn* PawnOwner = Cast<APawn>(GetOwner()); AController* Controller = PawnOwner->Controller; if (Controller == nullptr) { return nullptr; } FVector CamLoc; FRotator CamRot; Controller->GetPlayerViewPoint(CamLoc, CamRot); const FVector TraceStart = CamLoc; const FVector Direction = CamRot.Vector(); const FVector TraceEnd = TraceStart + (Direction * MaxPickupDistance); FCollisionQueryParams TraceParams(TEXT("TraceActor"), true, PawnOwner); TraceParams.bTraceAsyncScene = true; TraceParams.bReturnPhysicalMaterial = false; TraceParams.bTraceComplex = false; FHitResult Hit(ForceInit); GetWorld()->LineTraceSingleByChannel(Hit, TraceStart, TraceEnd, ECC_Visibility, TraceParams); /* Check to see if we hit a staticmesh component that has physics simulation enabled */ UStaticMeshComponent* MeshComp = Cast<UStaticMeshComponent>(Hit.GetComponent()); if (MeshComp && MeshComp->IsSimulatingPhysics()) { return Hit.GetActor(); } return nullptr; }
// Sets default values AMotherActor::AMotherActor() { // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; UBoxComponent* Box = CreateDefaultSubobject<UBoxComponent>(TEXT("RootComponent")); RootComponent = Box; Box->InitBoxExtent(FVector(20.0f, 20.0f, 20.0f)); UBoxComponent* Box1 = CreateDefaultSubobject<UBoxComponent>(TEXT("Box")); Box1->InitBoxExtent(FVector(60.0f, 60.0f, 60.0f)); Box1->RelativeLocation = FVector(100.0f, 0.0f, 0.0f); USphereComponent* SphereComponent = CreateDefaultSubobject<USphereComponent>(TEXT("Sphere")); SphereComponent->InitSphereRadius(60.0f); SphereComponent->RelativeLocation = FVector(100.0f, 0.0f, 0.0f); UStaticMeshComponent* SphereVisual = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("VisualRepresentation")); static ConstructorHelpers::FObjectFinder<UStaticMesh> SphereVisualAsset(TEXT("/Game/StarterContent/Shapes/Shape_Sphere.Shape_Sphere")); if (SphereVisualAsset.Succeeded()) { SphereVisual->SetStaticMesh(SphereVisualAsset.Object); SphereVisual->SetRelativeLocation(FVector(0.0f, 0.0f, -100.0f)); SphereVisual->SetWorldScale3D(FVector(0.8f)); } Box1->AttachTo(RootComponent); SphereVisual->AttachTo(RootComponent); SphereComponent->AttachTo(RootComponent); UChildActorComponent * ChildActor = CreateDefaultSubobject<UChildActorComponent>(TEXT("InventoryCamera")); ChildActor->SetChildActorClass(AOrbitalActor::StaticClass()); ChildActor->CreateChildActor(); FVector position = GetActorLocation(); ChildActor->SetRelativeTransform(FTransform(position)); }
// Sets default values AFishBreadSellerTable::AFishBreadSellerTable() { // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; auto Root = CreateDefaultSubobject<USphereComponent>(TEXT("RootComponent")); RootComponent = Root; //카메라세팅 gameCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("GameCamera")); gameCamera->AttachTo(RootComponent); UStaticMeshComponent* boardmesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("board1")); boardmesh->AttachTo(RootComponent); /*static ConstructorHelpers::FObjectFinder<UDataTable> meshData(TEXT("DataTable'/Game/fishGames/Tables/StaticMesh.StaticMesh'")); if (meshData.Succeeded()) { auto meshTableobj = meshData.Object; FDTStaticMeshList* meshitem = meshTableobj->FindRow<FDTStaticMeshList>(TEXT("meshName"), "fishBread1"); //meshitem->staticmesh } */ }
FLightRayIntersection FStaticMeshStaticLightingMesh::IntersectLightRay(const FVector& Start,const FVector& End,bool bFindNearestIntersection) const { // Create the check structure with all the local space fun FHitResult Result(1.0f); // Do the line check FHitResult NewHitInfo; FCollisionQueryParams NewTraceParams( FStaticMeshStaticLightingMesh_IntersectLightRayName, true ); UStaticMeshComponent* StaticMeshComp = const_cast<UStaticMeshComponent*>(Primitive); const bool bIntersects = StaticMeshComp->LineTraceComponent( Result, Start, End, NewTraceParams ); // Setup a vertex to represent the intersection. FStaticLightingVertex IntersectionVertex; if(bIntersects) { IntersectionVertex.WorldPosition = Result.Location; IntersectionVertex.WorldTangentZ = Result.Normal; } else { IntersectionVertex.WorldPosition.Set(0,0,0); IntersectionVertex.WorldTangentZ.Set(0,0,1); } return FLightRayIntersection(bIntersects,IntersectionVertex); }
// Sets default values ACollidingPawn::ACollidingPawn() { // Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; // Tutorial code // Our root component will be a sphere that reats to Physics USphereComponent* SphereComponent = CreateDefaultSubobject<USphereComponent>(TEXT("RootComponent")); RootComponent = SphereComponent; SphereComponent->InitSphereRadius(40.0f); SphereComponent->SetCollisionProfileName(TEXT("Pawn")); // Creating and correctly Positioning the Mesh component so that it fits the sphere collision UStaticMeshComponent* SphereVisual = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("VisualRepresentation")); SphereVisual->AttachTo(RootComponent); static ConstructorHelpers::FObjectFinder<UStaticMesh> SphereVisualAsset(TEXT("/Game/StarterContent/Shapes/Shape_Sphere.Shape_Sphere")); if (SphereVisualAsset.Succeeded()) { SphereVisual->SetStaticMesh(SphereVisualAsset.Object); SphereVisual->SetRelativeLocation(FVector(0.0f, 0.0f,-40.0f)); SphereVisual->SetWorldScale3D(FVector(0.8f)); } // Particle system Creation, Positioning (Offset) OurParticleSystem = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("MovementParticles")); OurParticleSystem->AttachTo(SphereVisual); OurParticleSystem->bAutoActivate = false; OurParticleSystem->SetRelativeLocation(FVector(-20.0f,0.0f,0.0f)); static ConstructorHelpers::FObjectFinder<UParticleSystem> ParticleAsset(TEXT("/Game/StarterContent/Particles/P_Fire.P_Fire")); if (ParticleAsset.Succeeded()) { OurParticleSystem->SetTemplate(ParticleAsset.Object); } // SpringArm creation for a smooth and fast Camera Experience ( We could have just avoided this springArm ) but for the sake of smoothness USpringArmComponent* SpringArm = CreateAbstractDefaultSubobject<USpringArmComponent>(TEXT("CameraAttachmentArm")); SpringArm->AttachTo(RootComponent); SpringArm->RelativeRotation = FRotator(-45.0f,0.0f,0.0f); SpringArm->TargetArmLength = 400.0f; SpringArm->bEnableCameraLag = true; SpringArm->CameraLagSpeed = 3.0f; // Easy to create the Camera component and attach it to the built in Socket at the end of springArm UCameraComponent* ActualCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("ActualCamera")); ActualCamera->AttachTo(SpringArm, USpringArmComponent::SocketName); // Take control of the default player AutoPossessPlayer = EAutoReceiveInput::Player0; // creating an instance of our movement component, and telling it to update the root. OurMovementComponent = CreateDefaultSubobject<UCollidingPawnMovementComponent>(TEXT("CustomMovementComponent")); OurMovementComponent->UpdatedComponent = RootComponent; }
// Sets default values APawnCharacter::APawnCharacter() { // Stats moveSpeed = 300.0f; dodgeSpeed = 800.0f; // Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; // Our root component will be a sphere that reacts to physics USphereComponent* SphereComponent = CreateDefaultSubobject<USphereComponent>(TEXT("RootComponent")); RootComponent = SphereComponent; SphereComponent->InitSphereRadius(40.0f); SphereComponent->SetCollisionProfileName(TEXT("Pawn")); // Create and position a mesh component so we can see where our sphere is UStaticMeshComponent* SphereVisual = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("VisualRepresentation")); SphereVisual->AttachTo(RootComponent); static ConstructorHelpers::FObjectFinder<UStaticMesh> SphereVisualAsset(TEXT("/Game/StarterContent/Shapes/Shape_Sphere.Shape_Sphere")); if (SphereVisualAsset.Succeeded()) { SphereVisual->SetStaticMesh(SphereVisualAsset.Object); SphereVisual->SetRelativeLocation(FVector(0.0f, 0.0f, -40.0f)); SphereVisual->SetWorldScale3D(FVector(0.8f)); } // Use a spring arm to give the camera smooth, natural-feeling motion. USpringArmComponent* SpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraAttachmentArm")); SpringArm->AttachTo(RootComponent); SpringArm->RelativeRotation = FRotator(-75.f, 0.f, 0.f); SpringArm->TargetArmLength = 800.0f; SpringArm->bEnableCameraLag = true; SpringArm->CameraLagSpeed = 5.0f; // Create a camera and attach to our spring arm UCameraComponent* Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("ActualCamera")); Camera->AttachTo(SpringArm, USpringArmComponent::SocketName); // Take control of the default player AutoPossessPlayer = EAutoReceiveInput::Player0; // Create an instance of our movement component, and tell it to update the root. OurMovementComponent = CreateDefaultSubobject<UPawnCharacterMovementComponent>(TEXT("CustomMovementComponent")); OurMovementComponent->UpdatedComponent = RootComponent; OurMovementComponent->setMoveSpeed(moveSpeed); }
void USCarryObjectComponent::OnPickupMulticast_Implementation(AActor* FocusActor) { if (FocusActor && FocusActor->IsRootComponentMovable()) { /* Find the static mesh (if any) to disable physics simulation while carried Filter by objects that are physically simulated and can therefor be picked up */ UStaticMeshComponent* MeshComp = Cast<UStaticMeshComponent>(FocusActor->GetComponentByClass(UStaticMeshComponent::StaticClass())); if (MeshComp && MeshComp->IsSimulatingPhysics()) { MeshComp->SetCollisionEnabled(ECollisionEnabled::QueryOnly); MeshComp->SetSimulatePhysics(false); } FocusActor->AttachToComponent(this, FAttachmentTransformRules::KeepWorldTransform); } }
void USCarryObjectComponent::OnDropMulticast_Implementation() { AActor* CarriedActor = GetCarriedActor(); if (CarriedActor) { /* Find the static mesh (if any) to re-enable physics simulation */ UStaticMeshComponent* MeshComp = Cast<UStaticMeshComponent>(CarriedActor->GetComponentByClass(UStaticMeshComponent::StaticClass())); if (MeshComp) { MeshComp->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); MeshComp->SetSimulatePhysics(true); } CarriedActor->GetRootComponent()->DetachFromComponent(FDetachmentTransformRules::KeepWorldTransform); } }
void UCarlaSettingsDelegate::SetAllRoads(UWorld* world, const float max_draw_distance, const TArray<FStaticMaterial> &road_pieces_materials) const { if(!world||!IsValid(world)||world->IsPendingKill()) return; AsyncTask(ENamedThreads::GameThread, [=](){ if(!world||!IsValid(world)||world->IsPendingKill()) return; TArray<AActor*> actors; UGameplayStatics::GetAllActorsWithTag(world, UCarlaSettings::CARLA_ROAD_TAG,actors); for(int32 i=0; i<actors.Num(); i++) { AActor* actor = actors[i]; if(!IsValid(actor) || actor->IsPendingKill()) continue; TArray<UActorComponent*> components = actor->GetComponentsByClass(UStaticMeshComponent::StaticClass()); for(int32 j=0; j<components.Num(); j++) { UStaticMeshComponent* staticmeshcomponent = Cast<UStaticMeshComponent>(components[j]); if(staticmeshcomponent) { staticmeshcomponent->bAllowCullDistanceVolume = (max_draw_distance>0); staticmeshcomponent->bUseAsOccluder = false; staticmeshcomponent->LDMaxDrawDistance = max_draw_distance; staticmeshcomponent->CastShadow = (max_draw_distance==0); if(road_pieces_materials.Num()>0) { TArray<FName> meshslotsnames = staticmeshcomponent->GetMaterialSlotNames(); for(int32 k=0; k<meshslotsnames.Num(); k++) { const FName &slotname = meshslotsnames[k]; road_pieces_materials.ContainsByPredicate( [staticmeshcomponent,slotname](const FStaticMaterial& material) { if(material.MaterialSlotName.IsEqual(slotname)) { staticmeshcomponent->SetMaterial( staticmeshcomponent->GetMaterialIndex(slotname), material.MaterialInterface ); return true; } else return false; }); } } } } } }); //,DELAY_TIME_TO_SET_ALL_ROADS, false); }
void AFlarePlanetarium::PrepareCelestialBody(FFlareCelestialBody* Body, FPreciseVector Offset, double AngleOffset) { CelestialBodyPosition BodyPosition; BodyPosition.Body = Body; FPreciseVector Location = Offset + Body->AbsoluteLocation; BodyPosition.AlignedLocation = Location.RotateAngleAxis(AngleOffset, FPreciseVector(0,1,0)); BodyPosition.Radius = Body->Radius; BodyPosition.Distance = BodyPosition.AlignedLocation.Size(); BodyPosition.TotalRotation = Body->RotationAngle + AngleOffset; // Find the celestial body component UStaticMeshComponent* BodyComponent = NULL; TArray<UActorComponent*> Components = GetComponentsByClass(UStaticMeshComponent::StaticClass()); for (int32 ComponentIndex = 0; ComponentIndex < Components.Num(); ComponentIndex++) { UStaticMeshComponent* ComponentCandidate = Cast<UStaticMeshComponent>(Components[ComponentIndex]); if (ComponentCandidate && ComponentCandidate->GetName() == Body->Identifier.ToString() ) { BodyComponent = ComponentCandidate; break; } } if (BodyComponent) { BodyPosition.BodyComponent = BodyComponent; BodyPositions.Add(BodyPosition); } else { FLOGV("AFlarePlanetarium::PrepareCelestialBody : no planetarium component for celestial body '%s'", *(Body->Identifier.ToString())); } if (Body == &Sun) { SunOcclusionAngle = FPreciseMath::Asin(BodyPosition.Radius / BodyPosition.Distance); SunPhase = FMath::UnwindRadians(FMath::Atan2(BodyPosition.AlignedLocation.Z, BodyPosition.AlignedLocation.X)); } for (int SatteliteIndex = 0; SatteliteIndex < Body->Sattelites.Num(); SatteliteIndex++) { FFlareCelestialBody* CelestialBody = &Body->Sattelites[SatteliteIndex]; PrepareCelestialBody(CelestialBody, Offset, AngleOffset); } }
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 RefreshCollisionChange(const UStaticMesh* StaticMesh) { for (FObjectIterator Iter(UStaticMeshComponent::StaticClass()); Iter; ++Iter) { UStaticMeshComponent* StaticMeshComponent = Cast<UStaticMeshComponent>(*Iter); if (StaticMeshComponent->StaticMesh == StaticMesh) { // it needs to recreate IF it already has been created if (StaticMeshComponent->IsPhysicsStateCreated()) { StaticMeshComponent->RecreatePhysicsState(); } } } FEditorSupportDelegates::RedrawAllViewports.Broadcast(); }
void SStaticMeshEditorViewport::UpdatePreviewMesh(UStaticMesh* InStaticMesh) { { const int32 SocketedComponentCount = SocketPreviewMeshComponents.Num(); for(int32 i = 0; i < SocketedComponentCount; ++i) { UStaticMeshComponent* SocketPreviewMeshComponent = SocketPreviewMeshComponents[i]; if( SocketPreviewMeshComponent ) { PreviewScene.RemoveComponent(SocketPreviewMeshComponent); } } SocketPreviewMeshComponents.Empty(); } if (PreviewMeshComponent) { PreviewScene.RemoveComponent(PreviewMeshComponent); PreviewMeshComponent = NULL; } PreviewMeshComponent = ConstructObject<UStaticMeshComponent>(UStaticMeshComponent::StaticClass()); PreviewMeshComponent->SetStaticMesh(InStaticMesh); PreviewScene.AddComponent(PreviewMeshComponent,FTransform::Identity); const int32 SocketCount = InStaticMesh->Sockets.Num(); SocketPreviewMeshComponents.Reserve(SocketCount); for(int32 i = 0; i < SocketCount; ++i) { UStaticMeshSocket* Socket = InStaticMesh->Sockets[i]; UStaticMeshComponent* SocketPreviewMeshComponent = NULL; if( Socket && Socket->PreviewStaticMesh ) { SocketPreviewMeshComponent = ConstructObject<UStaticMeshComponent>(UStaticMeshComponent::StaticClass()); SocketPreviewMeshComponent->SetStaticMesh(Socket->PreviewStaticMesh); SocketPreviewMeshComponent->SnapTo(PreviewMeshComponent, Socket->SocketName); SocketPreviewMeshComponents.Add(SocketPreviewMeshComponent); PreviewScene.AddComponent(SocketPreviewMeshComponent, FTransform::Identity); } } EditorViewportClient->SetPreviewMesh(InStaticMesh, PreviewMeshComponent); }
// Sets default values APawnWithCamera::APawnWithCamera() { // Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; // Our root component will be a sphere that reacts to physics USphereComponent* SphereComponent = CreateDefaultSubobject<USphereComponent>(TEXT("RootComponent")); RootComponent = SphereComponent; SphereComponent->InitSphereRadius(40.0f); SphereComponent->SetCollisionProfileName(TEXT("Pawn")); // Create and position a mesh component so we can see where our sphere is UStaticMeshComponent* SphereVisual = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("VisualRepresentation")); SphereVisual->AttachTo(RootComponent); static ConstructorHelpers::FObjectFinder<UStaticMesh> SphereVisualAsset(TEXT("/Game/StarterContent/Shapes/Shape_Sphere.Shape_Sphere")); if (SphereVisualAsset.Succeeded()) { SphereVisual->SetStaticMesh(SphereVisualAsset.Object); SphereVisual->SetRelativeLocation(FVector(0.0f, 0.0f, -40.0f)); SphereVisual->SetWorldScale3D(FVector(0.8f)); } //Create our camera sprinf OurCameraSpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraSpringArm")); OurCameraSpringArm->AttachTo(RootComponent); OurCameraSpringArm->SetRelativeLocationAndRotation(FVector(4.0f, 0.0f, 30.0f), FRotator(-60.0f, 0.0f, 0.0f)); OurCameraSpringArm->TargetArmLength = 300.f; OurCameraSpringArm->bEnableCameraLag = true; OurCameraSpringArm->CameraLagSpeed = 3.0f; OurCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("GameCamera")); OurCamera->AttachTo(OurCameraSpringArm, USpringArmComponent::SocketName); OurMovementComponent = CreateDefaultSubobject<UCollidingPawnMovementComponent>(TEXT("CustomMovementComponent")); OurMovementComponent->UpdatedComponent = RootComponent; //Take control of the default Player AutoPossessPlayer = EAutoReceiveInput::Player0; speenIncrease = 2.0f; speed = 100.f; }
void SStaticMeshEditorViewport::UpdatePreviewSocketMeshes() { UStaticMesh* const PreviewStaticMesh = PreviewMeshComponent ? PreviewMeshComponent->StaticMesh : NULL; if( PreviewStaticMesh ) { const int32 SocketedComponentCount = SocketPreviewMeshComponents.Num(); const int32 SocketCount = PreviewStaticMesh->Sockets.Num(); const int32 IterationCount = FMath::Max(SocketedComponentCount, SocketCount); for(int32 i = 0; i < IterationCount; ++i) { if(i >= SocketCount) { // Handle removing an old component UStaticMeshComponent* SocketPreviewMeshComponent = SocketPreviewMeshComponents[i]; PreviewScene.RemoveComponent(SocketPreviewMeshComponent); SocketPreviewMeshComponents.RemoveAt(i, SocketedComponentCount - i); break; } else if(UStaticMeshSocket* Socket = PreviewStaticMesh->Sockets[i]) { UStaticMeshComponent* SocketPreviewMeshComponent = NULL; // Handle adding a new component if(i >= SocketedComponentCount) { SocketPreviewMeshComponent = ConstructObject<UStaticMeshComponent>(UStaticMeshComponent::StaticClass()); PreviewScene.AddComponent(SocketPreviewMeshComponent, FTransform::Identity); SocketPreviewMeshComponents.Add(SocketPreviewMeshComponent); } else { SocketPreviewMeshComponent = SocketPreviewMeshComponents[i]; } SocketPreviewMeshComponent->SetStaticMesh(Socket->PreviewStaticMesh); SocketPreviewMeshComponent->SnapTo(PreviewMeshComponent, Socket->SocketName); } } } }
void ASCharacter::DropWeapon() { if (Role < ROLE_Authority) { ServerDropWeapon(); return; } if (CurrentWeapon) { FVector CamLoc; FRotator CamRot; if (Controller == nullptr) return; /* Find a location to drop the item, slightly in front of the player. */ Controller->GetPlayerViewPoint(CamLoc, CamRot); const FVector Direction = CamRot.Vector(); const FVector SpawnLocation = GetActorLocation() + (Direction * DropItemDistance); FActorSpawnParameters SpawnInfo; SpawnInfo.bNoCollisionFail = true; ASWeaponPickup* NewWeaponPickup = GetWorld()->SpawnActor<ASWeaponPickup>(CurrentWeapon->WeaponPickupClass, SpawnLocation, FRotator::ZeroRotator, SpawnInfo); if (NewWeaponPickup) { /* Apply torque to make it spin when dropped. */ UStaticMeshComponent* MeshComp = NewWeaponPickup->GetMeshComponent(); if (MeshComp) { MeshComp->SetSimulatePhysics(true); MeshComp->AddTorque(FVector(1, 1, 1) * 4000000); } } RemoveWeapon(CurrentWeapon); } }
void AManaJourneyCharacter::equipItem(AActor* actorToEquip, FName SocketName) { // set default properties or the equipment in Editor if (actorToEquip) { actorToEquip->SetActorEnableCollision(false); actorToEquip->GetRootComponent()->SetMobility(EComponentMobility::Movable); actorToEquip->AttachRootComponentTo(this->GetMesh(), SocketName, EAttachLocation::SnapToTargetIncludingScale, false); // remove any custom depth for equipped items TArray<UStaticMeshComponent*> StaticMeshesList; actorToEquip->GetComponents<UStaticMeshComponent>(StaticMeshesList); for (int32 i = 0; i < StaticMeshesList.Num(); i++) { UStaticMeshComponent* StaticMeshComponent = StaticMeshesList[i]; StaticMeshComponent->SetRenderCustomDepth(false); } } }
// Sets default values AKrofna_CPP::AKrofna_CPP() { // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; UStaticMeshComponent *Krofna = CreateDefaultSubobject<UStaticMeshComponent,UStaticMeshComponent>(TEXT("krofnica")); URotatingMovementComponent *Rotacija = CreateDefaultSubobject<URotatingMovementComponent, URotatingMovementComponent>(TEXT("rotaciona komponenta")); UPointLightComponent *Svetlo1 = CreateDefaultSubobject <UPointLightComponent, UPointLightComponent>(TEXT("Svetlo1")); UPointLightComponent *Svetlo2 = CreateDefaultSubobject <UPointLightComponent, UPointLightComponent>(TEXT("Svetlo2")); USphereComponent *Kolizija = CreateDefaultSubobject <USphereComponent, USphereComponent>(TEXT("Kolizija")); Kolizija->SetSphereRadius(65.f); Kolizija->Activate(true); Kolizija->bGenerateOverlapEvents = true; Kolizija->SetRelativeLocation(FVector(0,0,18.f)); this->RootComponent = Krofna; Kolizija->AttachTo(RootComponent); Svetlo1->AttachTo(RootComponent); Svetlo2->AttachTo(RootComponent); Svetlo1->SetRelativeLocation(FVector(0, 0, 65)); Svetlo2->SetRelativeLocation(FVector(0, 0, -45)); Svetlo1->SetLightColor(FLinearColor(0.65f, 1.f, 0.875f)); Svetlo2->SetLightColor(FLinearColor(0.45f, 1.f, 0.82f)); this->DisableComponentsSimulatePhysics(); Krofna->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Overlap); static ConstructorHelpers::FObjectFinder<UStaticMesh> Krofna_SM(TEXT("StaticMesh'/Game/StarterContent/Shapes/Shape_Torus.Shape_Torus'")); Krofna->SetStaticMesh(Krofna_SM.Object); static ConstructorHelpers::FObjectFinder<UMaterial> Krofna_M(TEXT("Material'/Game/StarterContent/Materials/M_Metal_Gold.M_Metal_Gold'")); Krofna->SetMaterial(0, Krofna_M.Object); Rotacija->SetActive(true); Rotacija->RotationRate = FRotator(120,120,120); this->SetActorEnableCollision(true); OnActorBeginOverlap.AddDynamic(this, &AKrofna_CPP::OnBeginOverlap); }
// FStaticLightingTextureMapping interface void FStaticMeshStaticLightingTextureMapping::Apply(FQuantizedLightmapData* QuantizedData, const TMap<ULightComponent*,FShadowMapData2D*>& ShadowMapData) { UStaticMeshComponent* StaticMeshComponent = Primitive.Get(); if (StaticMeshComponent) { // Should have happened at a higher level check(!StaticMeshComponent->IsRegistered()); // The rendering thread reads from LODData and IrrelevantLights, therefore // the component must have finished detaching from the scene on the rendering // thread before it is safe to continue. check(StaticMeshComponent->AttachmentCounter.GetValue() == 0); // Ensure LODData has enough entries in it, free not required. StaticMeshComponent->SetLODDataCount(LODIndex + 1, StaticMeshComponent->StaticMesh->GetNumLODs()); FStaticMeshComponentLODInfo& ComponentLODInfo = StaticMeshComponent->LODData[LODIndex]; ELightMapPaddingType PaddingType = GAllowLightmapPadding ? LMPT_NormalPadding : LMPT_NoPadding; const bool bHasNonZeroData = (QuantizedData != NULL && QuantizedData->HasNonZeroData()); // We always create a light map if the surface either has any non-zero lighting data, or if the surface has a shadow map. The runtime // shaders are always expecting a light map in the case of a shadow map, even if the lighting is entirely zero. This is simply to reduce // the number of shader permutations to support in the very unlikely case of a unshadowed surfaces that has lighting values of zero. const bool bNeedsLightMap = bHasNonZeroData || ShadowMapData.Num() > 0 || Mesh->RelevantLights.Num() > 0 || (QuantizedData != NULL && QuantizedData->bHasSkyShadowing); if (bNeedsLightMap) { // Create a light-map for the primitive. ComponentLODInfo.LightMap = FLightMap2D::AllocateLightMap( StaticMeshComponent, QuantizedData, StaticMeshComponent->Bounds, PaddingType, LMF_Streamed ); } else { ComponentLODInfo.LightMap = NULL; } if (ShadowMapData.Num() > 0) { ComponentLODInfo.ShadowMap = FShadowMap2D::AllocateShadowMap( StaticMeshComponent, ShadowMapData, StaticMeshComponent->Bounds, PaddingType, SMF_Streamed ); } else { ComponentLODInfo.ShadowMap = NULL; } // Build the list of statically irrelevant lights. // IrrelevantLights was cleared in InvalidateLightingCacheDetailed for(int32 LightIndex = 0;LightIndex < Mesh->RelevantLights.Num();LightIndex++) { const ULightComponent* Light = Mesh->RelevantLights[LightIndex]; // Check if the light is stored in the light-map. const bool bIsInLightMap = ComponentLODInfo.LightMap && ComponentLODInfo.LightMap->LightGuids.Contains(Light->LightGuid); // Check if the light is stored in the shadow-map. const bool bIsInShadowMap = ComponentLODInfo.ShadowMap && ComponentLODInfo.ShadowMap->LightGuids.Contains(Light->LightGuid); // Add the light to the statically irrelevant light list if it is in the potentially relevant light list, but didn't contribute to the light-map. if(!bIsInLightMap && !bIsInShadowMap) { StaticMeshComponent->IrrelevantLights.AddUnique(Light->LightGuid); } } StaticMeshComponent->bHasCachedStaticLighting = true; // Mark the primitive's package as dirty. StaticMeshComponent->MarkPackageDirty(); } }
// Sets default values AMyDrone::AMyDrone() { // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; // Our root component will be a sphere that reacts to physics SphereComponent = CreateDefaultSubobject<USphereComponent>(TEXT("RootComponent")); RootComponent = SphereComponent; SphereComponent->InitSphereRadius(20.0f); SphereComponent->BodyInstance.SetCollisionEnabled(ECollisionEnabled::QueryOnly); SphereComponent->BodyInstance.SetResponseToAllChannels(ECR_Overlap); OnActorBeginOverlap.AddDynamic(this, &AMyDrone::OnOverlapBegin); // Create and position a mesh component to fuselage UStaticMeshComponent* fuselageMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("VisualRepresentation")); fuselageMesh->AttachTo(RootComponent); static ConstructorHelpers::FObjectFinder<UStaticMesh> FuselageVisualAsset(TEXT("/Game/unreal_fuselage.unreal_fuselage")); if (FuselageVisualAsset.Succeeded()) { fuselageMesh->SetStaticMesh(FuselageVisualAsset.Object); fuselageMesh->SetRelativeLocation(FVector(0.0f, 0.0f, 0.0f)); // no translation for now fuselageMesh->SetWorldScale3D(FVector(1.0f)); // no scaling for now } // find elevon in assets library static ConstructorHelpers::FObjectFinder<UStaticMesh> ElevonVisualAsset(TEXT("/Game/elevon.elevon")); // Create and position a mesh component to elevon 1 elevon1Mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Elevon1Mesh")); elevon1Mesh->AttachTo(RootComponent); if (ElevonVisualAsset.Succeeded()) { elevon1Mesh->SetStaticMesh(ElevonVisualAsset.Object); elevon1Mesh->SetRelativeLocation(FVector(-12.0f, 12.0f, 0.0f)); // no translation for now elevon1Mesh->SetWorldScale3D(FVector(1.0f)); // no scaling for now } // Create and position a mesh component to elevon 2 elevon2Mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Elevon2Mesh")); elevon2Mesh->AttachTo(RootComponent); if (ElevonVisualAsset.Succeeded()) { elevon2Mesh->SetStaticMesh(ElevonVisualAsset.Object); elevon2Mesh->SetRelativeLocation(FVector(-12.0f, -12.0f, 0.0f)); // no translation for now elevon2Mesh->SetWorldScale3D(FVector(1.0f)); // no scaling for now } // Create a particle system that we can activate or deactivate DroneParticleSystem = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("MovementParticles")); DroneParticleSystem->AttachTo(fuselageMesh); DroneParticleSystem->bAutoActivate = false; DroneParticleSystem->SetRelativeLocation(FVector(0.0f, 0.0f, 0.0f)); static ConstructorHelpers::FObjectFinder<UParticleSystem> ParticleAsset(TEXT("/Game/StarterContent/Particles/P_Fire.P_Fire")); if (ParticleAsset.Succeeded()) { DroneParticleSystem->SetTemplate(ParticleAsset.Object); } // inyit cvs table handlers UCurveTable* expTable; static ConstructorHelpers::FObjectFinder<UCurveTable> expTable_BP(TEXT("CurveTable'/Game/Data/testtable.testtable'")); expTable = expTable_BP.Object; // not sure what this is, but it seems necessary static const FString ContextString(TEXT("GENERAL")); // here we link curves to experimental position CSV data curveX = expTable->FindCurve(*FString::Printf(TEXT("X")), ContextString); curveY = expTable->FindCurve(*FString::Printf(TEXT("Y")), ContextString); curveZ = expTable->FindCurve(*FString::Printf(TEXT("Z")), ContextString); // here we link curves to experimental quaternion CSV data curveQ0 = expTable->FindCurve(*FString::Printf(TEXT("Q0")), ContextString); curveQ1 = expTable->FindCurve(*FString::Printf(TEXT("Q1")), ContextString); curveQ2 = expTable->FindCurve(*FString::Printf(TEXT("Q2")), ContextString); curveQ3 = expTable->FindCurve(*FString::Printf(TEXT("Q3")), ContextString); // here we link curves to experimental elevon CSV data curveD1 = expTable->FindCurve(*FString::Printf(TEXT("D1")), ContextString); curveD2 = expTable->FindCurve(*FString::Printf(TEXT("D2")), ContextString); }
void UJanusExporterTool::Export() { TArray<UObject*> ObjectsToExport; FString Root = FString(ExportPath); // copy so we dont mess with the original reference FString Index = "<html>\n\t<head>\n\t\t<title>Unreal Export</title>\n\t</head>\n\t<body>\n\t\t<FireBoxRoom>\n\t\t\t<Assets>"; TArray<AActor*> ActorsExported; TArray<UStaticMesh*> StaticMeshesExp; TArray<FString> TexturesExp; TArray<FString> MaterialsExported; for (TObjectIterator<AActor> Itr; Itr; ++Itr) { AActor *Actor = *Itr; FString Name = Actor->GetName(); /*if (!Name.StartsWith("SM_Floor_R")) { continue; }*/ if (Actor->IsHiddenEd()) { continue; } ActorsExported.Add(Actor); TArray<UStaticMeshComponent*> StaticMeshes; Actor->GetComponents<UStaticMeshComponent>(StaticMeshes); for (int32 i = 0; i < StaticMeshes.Num(); i++) { UStaticMeshComponent* Component = StaticMeshes[i]; UStaticMesh *Mesh = Component->StaticMesh; if (!Mesh) { continue; } if (Component->LODData.Num() > 0) //if (false) { FStaticMeshComponentLODInfo* LODInfo = &Component->LODData[0]; FLightMap* LightMap = LODInfo->LightMap; FShadowMap* ShadowMap = LODInfo->ShadowMap; if (LightMap != NULL) { FLightMap2D* LightMap2D = LightMap->GetLightMap2D(); UTexture2D* Texture = LightMap2D->GetTexture(0); // 0 = HQ LightMap FString TexName = Texture->GetName(); if (TexturesExp.Contains(TexName)) { continue; } TexturesExp.Add(TexName); ExportPNG(Texture, Root); } if (ShadowMap != NULL) { FShadowMap2D* ShadowMap2D = ShadowMap->GetShadowMap2D(); UShadowMapTexture2D* ShadowTex = ShadowMap2D->GetTexture(); FString TexName = ShadowTex->GetName(); if (TexturesExp.Contains(TexName)) { continue; } TexturesExp.Add(TexName); ExportPNG(ShadowTex, Root); } } if (!StaticMeshesExp.Contains(Mesh)) { StaticMeshesExp.Add(Mesh); ExportFBX(Mesh, Root); } TArray<UMaterialInterface*> Materials = Component->GetMaterials(); for (int32 j = 0; j < Materials.Num(); j++) { UMaterialInterface* Material = Materials[j]; if (!Material) { continue; } FString MatName = Material->GetName(); if (MaterialsExported.Contains(MatName)) { continue; } MaterialsExported.Add(MatName); ExportMaterial(Root, Material, &TexturesExp); } } } // Models before textures so we can start showing the scene faster (textures take too long to load) for (int32 i = 0; i < StaticMeshesExp.Num(); i++) { UStaticMesh *mesh = StaticMeshesExp[i]; Index.Append("\n\t\t\t\t<AssetObject id=\"" + mesh->GetName() + "\" src=\"" + mesh->GetName() + ".fbx\" />"); } for (int32 i = 0; i < TexturesExp.Num(); i++) { FString Path = TexturesExp[i]; Index.Append("\n\t\t\t\t<AssetImage id=\"" + Path + "\" src=\"" + Path + ".png\" />"); } Index.Append("\n\t\t\t</Assets>\n\t\t\t<Room>"); for (int32 i = 0; i < ActorsExported.Num(); i++) { AActor *Actor = ActorsExported[i]; TArray<UStaticMeshComponent*> StaticMeshes; Actor->GetComponents<UStaticMeshComponent>(StaticMeshes); for (int32 i = 0; i < StaticMeshes.Num(); i++) { UStaticMeshComponent* Component = StaticMeshes[i]; UStaticMesh *Mesh = Component->StaticMesh; if (!Mesh) { continue; } FString ImageID = ""; TArray<UMaterialInterface*> Materials = Component->GetMaterials(); for (int32 j = 0; j < Materials.Num(); j++) { UMaterialInterface* Material = Materials[j]; if (!Material) { continue; } ImageID = Material->GetName() + "_BaseColor"; break; } if (ImageID == "") { Index.Append("\n\t\t\t\t<Object collision_id=\"" + Mesh->GetName() + "\" id=\"" + Mesh->GetName() + "\" lighting=\"true\" pos=\""); } else { Index.Append("\n\t\t\t\t<Object collision_id=\"" + Mesh->GetName() + "\" id=\"" + Mesh->GetName() + "\" image_id=\"" + ImageID + "\" lighting=\"true\" pos=\""); } FRotator Rot = Actor->GetActorRotation(); FVector XDir = Rot.RotateVector(FVector::RightVector); FVector YDir = Rot.RotateVector(FVector::UpVector); FVector ZDir = Rot.RotateVector(FVector::ForwardVector); FVector Pos = Actor->GetActorLocation() * UniformScale; FVector Sca = Actor->GetActorScale(); Pos = ChangeSpace(Pos); Sca = ChangeSpaceScalar(Sca) * UniformScale; XDir = ChangeSpace(XDir); YDir = ChangeSpace(YDir); ZDir = ChangeSpace(ZDir); FVector Sign = GetSignVector(Sca); Index.Append(FString::SanitizeFloat(Pos.X) + " " + FString::SanitizeFloat(Pos.Y) + " " + FString::SanitizeFloat(Pos.Z)); if (Sca.X < 0 || Sca.Y < 0 || Sca.Z < 0) { Index.Append("\" cull_face=\"front"); } Index.Append("\" scale=\""); Index.Append(FString::SanitizeFloat(Sca.X) + " " + FString::SanitizeFloat(Sca.Y) + " " + FString::SanitizeFloat(Sca.Z)); Index.Append("\" xdir=\""); Index.Append(FString::SanitizeFloat(XDir.X) + " " + FString::SanitizeFloat(XDir.Y) + " " + FString::SanitizeFloat(XDir.Z)); Index.Append("\" ydir=\""); Index.Append(FString::SanitizeFloat(YDir.X) + " " + FString::SanitizeFloat(YDir.Y) + " " + FString::SanitizeFloat(YDir.Z)); Index.Append("\" zdir=\""); Index.Append(FString::SanitizeFloat(ZDir.X) + " " + FString::SanitizeFloat(ZDir.Y) + " " + FString::SanitizeFloat(ZDir.Z)); Index.Append("\" />"); } } Index.Append("\n\t\t\t</Room>\n\t\t</FireBoxRoom>\n\t</body>\n</html>"); FString IndexPath = FString(ExportPath).Append("index.html"); FFileHelper::SaveStringToFile(Index, *IndexPath); }
bool SMaterialEditorViewport::SetPreviewAsset(UObject* InAsset) { if (!MaterialEditorPtr.Pin()->ApproveSetPreviewAsset(InAsset)) { return false; } // Unregister the current component if (PreviewMeshComponent != nullptr) { PreviewScene.RemoveComponent(PreviewMeshComponent); PreviewMeshComponent = nullptr; } FTransform Transform = FTransform::Identity; if (UStaticMesh* StaticMesh = Cast<UStaticMesh>(InAsset)) { // Special case handling for static meshes, to use more accurate bounds via a subclass UStaticMeshComponent* NewSMComponent = NewObject<UMaterialEditorMeshComponent>(GetTransientPackage(), NAME_None, RF_Transient); NewSMComponent->SetStaticMesh(StaticMesh); PreviewMeshComponent = NewSMComponent; // Update the toolbar state implicitly through PreviewPrimType. if (StaticMesh == GUnrealEd->GetThumbnailManager()->EditorCylinder) { PreviewPrimType = TPT_Cylinder; } else if (StaticMesh == GUnrealEd->GetThumbnailManager()->EditorCube) { PreviewPrimType = TPT_Cube; } else if (StaticMesh == GUnrealEd->GetThumbnailManager()->EditorSphere) { PreviewPrimType = TPT_Sphere; } else if (StaticMesh == GUnrealEd->GetThumbnailManager()->EditorPlane) { // Need to rotate the plane so that it faces the camera Transform.SetRotation(FQuat(FRotator(0, 90, 0))); PreviewPrimType = TPT_Plane; } else { PreviewPrimType = TPT_None; } } else if (InAsset != nullptr) { // Fall back to the component asset broker if (TSubclassOf<UActorComponent> ComponentClass = FComponentAssetBrokerage::GetPrimaryComponentForAsset(InAsset->GetClass())) { if (ComponentClass->IsChildOf(UMeshComponent::StaticClass())) { PreviewMeshComponent = NewObject<UMeshComponent>(GetTransientPackage(), ComponentClass, NAME_None, RF_Transient); FComponentAssetBrokerage::AssignAssetToComponent(PreviewMeshComponent, InAsset); PreviewPrimType = TPT_None; } } } // Add the new component to the scene if (PreviewMeshComponent != nullptr) { PreviewScene.AddComponent(PreviewMeshComponent, Transform); } // Make sure the preview material is applied to the component SetPreviewMaterial(PreviewMaterial); return (PreviewMeshComponent != nullptr); }
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 FComponentTypeRegistryData::AddBasicShapeComponents(TArray<FComponentClassComboEntryPtr>& SortedClassList) { FString BasicShapesHeading = LOCTEXT("BasicShapesHeading", "Basic Shapes").ToString(); const auto OnBasicShapeCreated = [](UActorComponent* Component) { UStaticMeshComponent* SMC = Cast<UStaticMeshComponent>(Component); if (SMC) { SMC->SetMaterial(0, LoadObject<UMaterial>(nullptr, TEXT("/Engine/BasicShapes/BasicShapeMaterial.BasicShapeMaterial"))); } }; { FComponentEntryCustomizationArgs Args; Args.AssetOverride = LoadObject<UStaticMesh>(nullptr, *UActorFactoryBasicShape::BasicCube.ToString()); Args.OnComponentCreated = FOnComponentCreated::CreateStatic(OnBasicShapeCreated); Args.ComponentNameOverride = LOCTEXT("BasicCubeShapeDisplayName", "Cube").ToString(); Args.IconOverrideBrushName = FName("ClassIcon.Cube"); Args.SortPriority = 2; { FComponentClassComboEntryPtr NewShape = MakeShareable(new FComponentClassComboEntry(BasicShapesHeading, UStaticMeshComponent::StaticClass(), true, EComponentCreateAction::SpawnExistingClass, Args)); SortedClassList.Add(NewShape); } { //Cube also goes in the common group FComponentClassComboEntryPtr NewShape = MakeShareable(new FComponentClassComboEntry(CommonClassGroup, UStaticMeshComponent::StaticClass(), false, EComponentCreateAction::SpawnExistingClass, Args)); SortedClassList.Add(NewShape); } } { FComponentEntryCustomizationArgs Args; Args.AssetOverride = LoadObject<UStaticMesh>(nullptr, *UActorFactoryBasicShape::BasicSphere.ToString()); Args.OnComponentCreated = FOnComponentCreated::CreateStatic(OnBasicShapeCreated); Args.ComponentNameOverride = LOCTEXT("BasicSphereShapeDisplayName", "Sphere").ToString(); Args.IconOverrideBrushName = FName("ClassIcon.Sphere"); Args.SortPriority = 2; { FComponentClassComboEntryPtr NewShape = MakeShareable(new FComponentClassComboEntry(BasicShapesHeading, UStaticMeshComponent::StaticClass(), true, EComponentCreateAction::SpawnExistingClass, Args)); SortedClassList.Add(NewShape); } { // Sphere also goes in the common group FComponentClassComboEntryPtr NewShape = MakeShareable(new FComponentClassComboEntry(CommonClassGroup, UStaticMeshComponent::StaticClass(), false, EComponentCreateAction::SpawnExistingClass, Args)); SortedClassList.Add(NewShape); } } { FComponentEntryCustomizationArgs Args; Args.AssetOverride = LoadObject<UStaticMesh>(nullptr, *UActorFactoryBasicShape::BasicCylinder.ToString()); Args.OnComponentCreated = FOnComponentCreated::CreateStatic(OnBasicShapeCreated); Args.ComponentNameOverride = LOCTEXT("BasicCylinderShapeDisplayName", "Cylinder").ToString(); Args.IconOverrideBrushName = FName("ClassIcon.Cylinder"); Args.SortPriority = 3; FComponentClassComboEntryPtr NewShape = MakeShareable(new FComponentClassComboEntry(BasicShapesHeading, UStaticMeshComponent::StaticClass(), true, EComponentCreateAction::SpawnExistingClass, Args)); SortedClassList.Add(NewShape); } { FComponentEntryCustomizationArgs Args; Args.AssetOverride = LoadObject<UStaticMesh>(nullptr, *UActorFactoryBasicShape::BasicCone.ToString()); Args.OnComponentCreated = FOnComponentCreated::CreateStatic(OnBasicShapeCreated); Args.ComponentNameOverride = LOCTEXT("BasicConeShapeDisplayName", "Cone").ToString(); Args.IconOverrideBrushName = FName("ClassIcon.Cone"); Args.SortPriority = 4; FComponentClassComboEntryPtr NewShape = MakeShareable(new FComponentClassComboEntry(BasicShapesHeading, UStaticMeshComponent::StaticClass(), true, EComponentCreateAction::SpawnExistingClass, Args)); SortedClassList.Add(NewShape); } }
void UStretchGizmoHandleGroup::UpdateGizmoHandleGroup( const FTransform& LocalToWorld, const FBox& LocalBounds, const FVector ViewLocation, bool bAllHandlesVisible, class UActorComponent* DraggingHandle, const TArray< UActorComponent* >& HoveringOverHandles, float AnimationAlpha, float GizmoScale, const float GizmoHoverScale, const float GizmoHoverAnimationDuration, bool& bOutIsHoveringOrDraggingThisHandleGroup ) { // Call parent implementation (updates hover animation) Super::UpdateGizmoHandleGroup(LocalToWorld, LocalBounds, ViewLocation, bAllHandlesVisible, DraggingHandle, HoveringOverHandles, AnimationAlpha, GizmoScale, GizmoHoverScale, GizmoHoverAnimationDuration, bOutIsHoveringOrDraggingThisHandleGroup ); for (int32 HandleIndex = 0; HandleIndex < Handles.Num(); ++HandleIndex) { FGizmoHandle& Handle = Handles[ HandleIndex ]; UStaticMeshComponent* StretchingHandle = Handle.HandleMesh; if (StretchingHandle != nullptr) // Can be null if no handle for this specific placement { const FTransformGizmoHandlePlacement HandlePlacement = MakeHandlePlacementForIndex( HandleIndex ); float GizmoHandleScale = GizmoScale; const float OffsetFromSide = GizmoHandleScale * (0.0f + // @todo vreditor tweak: Hard coded handle offset from side of primitive (1.0f - AnimationAlpha) * 10.0f); // @todo vreditor tweak: Animation offset // Make the handle bigger while hovered (but don't affect the offset -- we want it to scale about it's origin) GizmoHandleScale *= FMath::Lerp( 1.0f, GizmoHoverScale, Handle.HoverAlpha ); FVector HandleRelativeLocation = FVector::ZeroVector; for (int32 AxisIndex = 0; AxisIndex < 3; ++AxisIndex) { if (HandlePlacement.Axes[AxisIndex] == ETransformGizmoHandleDirection::Negative) // Negative direction { HandleRelativeLocation[AxisIndex] = LocalBounds.Min[AxisIndex] - OffsetFromSide; } else if (HandlePlacement.Axes[AxisIndex] == ETransformGizmoHandleDirection::Positive) // Positive direction { HandleRelativeLocation[AxisIndex] = LocalBounds.Max[AxisIndex] + OffsetFromSide; } else // ETransformGizmoHandleDirection::Center { HandleRelativeLocation[AxisIndex] = LocalBounds.GetCenter()[AxisIndex]; } } StretchingHandle->SetRelativeLocation( HandleRelativeLocation ); int32 CenterHandleCount, FacingAxisIndex, CenterAxisIndex; HandlePlacement.GetCenterHandleCountAndFacingAxisIndex( /* Out */ CenterHandleCount, /* Out */ FacingAxisIndex, /* Out */ CenterAxisIndex ); FRotator Rotator = FRotator::ZeroRotator; { // Back bottom left if (HandlePlacement.Axes[0] == ETransformGizmoHandleDirection::Negative && HandlePlacement.Axes[1] == ETransformGizmoHandleDirection::Negative && HandlePlacement.Axes[2] == ETransformGizmoHandleDirection::Negative) { Rotator.Yaw = 0.0f; Rotator.Pitch = 0.0f; } // Back bottom right else if (HandlePlacement.Axes[0] == ETransformGizmoHandleDirection::Negative && HandlePlacement.Axes[1] == ETransformGizmoHandleDirection::Positive && HandlePlacement.Axes[2] == ETransformGizmoHandleDirection::Negative) { Rotator.Yaw = -90.0f; Rotator.Pitch = 0.0f; } // Back top left else if (HandlePlacement.Axes[0] == ETransformGizmoHandleDirection::Negative && HandlePlacement.Axes[1] == ETransformGizmoHandleDirection::Negative && HandlePlacement.Axes[2] == ETransformGizmoHandleDirection::Positive) { Rotator.Yaw = 0.0f; Rotator.Pitch = -90.0f; } // Back top right else if (HandlePlacement.Axes[0] == ETransformGizmoHandleDirection::Negative && HandlePlacement.Axes[1] == ETransformGizmoHandleDirection::Positive && HandlePlacement.Axes[2] == ETransformGizmoHandleDirection::Positive) { Rotator.Yaw = -90.0f; Rotator.Pitch = -90.0f; } // Front bottom left else if (HandlePlacement.Axes[0] == ETransformGizmoHandleDirection::Positive && HandlePlacement.Axes[1] == ETransformGizmoHandleDirection::Negative && HandlePlacement.Axes[2] == ETransformGizmoHandleDirection::Negative) { Rotator.Yaw = 0.0f; Rotator.Pitch = 90.0f; } // Front bottom right else if (HandlePlacement.Axes[0] == ETransformGizmoHandleDirection::Positive && HandlePlacement.Axes[1] == ETransformGizmoHandleDirection::Positive && HandlePlacement.Axes[2] == ETransformGizmoHandleDirection::Negative) { Rotator.Yaw = 90.0f; Rotator.Pitch = 90.0f; } // Front top left else if (HandlePlacement.Axes[0] == ETransformGizmoHandleDirection::Positive && HandlePlacement.Axes[1] == ETransformGizmoHandleDirection::Negative && HandlePlacement.Axes[2] == ETransformGizmoHandleDirection::Positive) { Rotator.Yaw = 0.0f; Rotator.Pitch = -180.0f; } // Front top right else if (HandlePlacement.Axes[0] == ETransformGizmoHandleDirection::Positive && HandlePlacement.Axes[1] == ETransformGizmoHandleDirection::Positive && HandlePlacement.Axes[2] == ETransformGizmoHandleDirection::Positive) { Rotator.Yaw = 180.0f; Rotator.Pitch = -90.0f; } // Back left/right edge else if (HandlePlacement.Axes[0] == ETransformGizmoHandleDirection::Negative && HandlePlacement.Axes[1] != ETransformGizmoHandleDirection::Center) { Rotator.Yaw = 0.0f; Rotator.Pitch = 90.0f; } // Back bottom/top edge else if (HandlePlacement.Axes[0] == ETransformGizmoHandleDirection::Negative && HandlePlacement.Axes[2] != ETransformGizmoHandleDirection::Center) { Rotator.Yaw = 90.0f; Rotator.Pitch = 0.0f; } // Front left/right edge else if (HandlePlacement.Axes[0] == ETransformGizmoHandleDirection::Positive && HandlePlacement.Axes[1] != ETransformGizmoHandleDirection::Center) { Rotator.Yaw = 0.0f; Rotator.Pitch = 90.0f; } // Front bottom/top edge else if (HandlePlacement.Axes[0] == ETransformGizmoHandleDirection::Positive && HandlePlacement.Axes[2] != ETransformGizmoHandleDirection::Center) { Rotator.Yaw = 90.0f; Rotator.Pitch = 0.0f; } else { // Facing out from center of a face if (CenterHandleCount == 2) { const FQuat GizmoSpaceOrientation = GetAxisVector( FacingAxisIndex, HandlePlacement.Axes[FacingAxisIndex] ).ToOrientationQuat(); Rotator = GizmoSpaceOrientation.Rotator(); } else { // One of the left/right bottom or top edges } } } StretchingHandle->SetRelativeRotation( Rotator ); StretchingHandle->SetRelativeScale3D( FVector( GizmoHandleScale ) ); // Update material UpdateHandleColor( FacingAxisIndex, Handle, DraggingHandle, HoveringOverHandles ); } } }
void ASCharacter::DropWeapon() { if (Role < ROLE_Authority) { ServerDropWeapon(); return; } if (CurrentWeapon) { FVector CamLoc; FRotator CamRot; if (Controller == nullptr) { return; } /* Find a location to drop the item, slightly in front of the player. Perform ray trace to check for blocking objects or walls and to make sure we don't drop any item through the level mesh */ Controller->GetPlayerViewPoint(CamLoc, CamRot); FVector SpawnLocation; FRotator SpawnRotation = CamRot; const FVector Direction = CamRot.Vector(); const FVector TraceStart = GetActorLocation(); const FVector TraceEnd = GetActorLocation() + (Direction * DropWeaponMaxDistance); /* Setup the trace params, we are only interested in finding a valid drop position */ FCollisionQueryParams TraceParams; TraceParams.bTraceComplex = false; TraceParams.bReturnPhysicalMaterial = false; TraceParams.AddIgnoredActor(this); FHitResult Hit; GetWorld()->LineTraceSingleByChannel(Hit, TraceStart, TraceEnd, ECC_WorldDynamic, TraceParams); /* Find farthest valid spawn location */ if (Hit.bBlockingHit) { /* Slightly move away from impacted object */ SpawnLocation = Hit.ImpactPoint + (Hit.ImpactNormal * 20); } else { SpawnLocation = TraceEnd; } /* Spawn the "dropped" weapon */ FActorSpawnParameters SpawnInfo; SpawnInfo.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; ASWeaponPickup* NewWeaponPickup = GetWorld()->SpawnActor<ASWeaponPickup>(CurrentWeapon->WeaponPickupClass, SpawnLocation, FRotator::ZeroRotator, SpawnInfo); if (NewWeaponPickup) { /* Apply torque to make it spin when dropped. */ UStaticMeshComponent* MeshComp = NewWeaponPickup->GetMeshComponent(); if (MeshComp) { MeshComp->SetSimulatePhysics(true); MeshComp->AddTorque(FVector(1, 1, 1) * 4000000); } } RemoveWeapon(CurrentWeapon, true); } }
/** Updates GCurrentSelectedLightmapSample given a selected actor's components and the location of the click. */ void SetDebugLightmapSample(TArray<UActorComponent*>* Components, UModel* Model, int32 iSurf, FVector ClickLocation) { UStaticMeshComponent* SMComponent = NULL; if (Components) { // Find the first supported component for (int32 ComponentIndex = 0; ComponentIndex < Components->Num() && !SMComponent; ComponentIndex++) { SMComponent = Cast<UStaticMeshComponent>((*Components)[ComponentIndex]); if (SMComponent && (!SMComponent->StaticMesh || SMComponent->LODData.Num() == 0)) { SMComponent = NULL; } } } bool bFoundLightmapSample = false; // Only static mesh components and BSP handled for now if (SMComponent) { UStaticMesh* StaticMesh = SMComponent->StaticMesh; check(StaticMesh); check(StaticMesh->RenderData); check(StaticMesh->RenderData->LODResources.Num()); // Only supporting LOD0 const int32 LODIndex = 0; FStaticMeshLODResources& LODModel = StaticMesh->RenderData->LODResources[LODIndex]; FIndexArrayView Indices = LODModel.IndexBuffer.GetArrayView(); const bool bHasStaticLighting = SMComponent->HasStaticLighting(); if (bHasStaticLighting) { bool bUseTextureMap = false; int32 LightmapSizeX = 0; int32 LightmapSizeY = 0; SMComponent->GetLightMapResolution(LightmapSizeX, LightmapSizeY); if (LightmapSizeX > 0 && LightmapSizeY > 0 && StaticMesh->LightMapCoordinateIndex >= 0 && (uint32)StaticMesh->LightMapCoordinateIndex < LODModel.VertexBuffer.GetNumTexCoords() ) { bUseTextureMap = true; } else { bUseTextureMap = false; } // Search through the static mesh's triangles for the one that was hit (since we can't get triangle index from a line check) for(int32 TriangleIndex = 0; TriangleIndex < Indices.Num(); TriangleIndex += 3) { uint32 Index0 = Indices[TriangleIndex]; uint32 Index1 = Indices[TriangleIndex + 1]; uint32 Index2 = Indices[TriangleIndex + 2]; // Transform positions to world space FVector Position0 = SMComponent->ComponentToWorld.TransformPosition(LODModel.PositionVertexBuffer.VertexPosition(Index0)); FVector Position1 = SMComponent->ComponentToWorld.TransformPosition(LODModel.PositionVertexBuffer.VertexPosition(Index1)); FVector Position2 = SMComponent->ComponentToWorld.TransformPosition(LODModel.PositionVertexBuffer.VertexPosition(Index2)); FVector BaryCentricWeights; // Continue if click location is in the triangle and get its barycentric weights if (GetBarycentricWeights(Position0, Position1, Position2, ClickLocation, .001f, BaryCentricWeights)) { RestoreSelectedLightmapSample(); if (bUseTextureMap) { // Fetch lightmap UV's FVector2D LightmapUV0 = LODModel.VertexBuffer.GetVertexUV(Index0, StaticMesh->LightMapCoordinateIndex); FVector2D LightmapUV1 = LODModel.VertexBuffer.GetVertexUV(Index1, StaticMesh->LightMapCoordinateIndex); FVector2D LightmapUV2 = LODModel.VertexBuffer.GetVertexUV(Index2, StaticMesh->LightMapCoordinateIndex); // Interpolate lightmap UV's to the click location FVector2D InterpolatedUV = LightmapUV0 * BaryCentricWeights.X + LightmapUV1 * BaryCentricWeights.Y + LightmapUV2 * BaryCentricWeights.Z; int32 PaddedSizeX = LightmapSizeX; int32 PaddedSizeY = LightmapSizeY; if (GLightmassDebugOptions.bPadMappings && GAllowLightmapPadding && LightmapSizeX - 2 > 0 && LightmapSizeY - 2 > 0) { PaddedSizeX -= 2; PaddedSizeY -= 2; } const int32 LocalX = FMath::TruncToInt(InterpolatedUV.X * PaddedSizeX); const int32 LocalY = FMath::TruncToInt(InterpolatedUV.Y * PaddedSizeY); if (LocalX < 0 || LocalX >= PaddedSizeX || LocalY < 0 || LocalY >= PaddedSizeY) { UE_LOG(LogStaticLightingSystem, Log, TEXT("Texel selection failed because the lightmap UV's wrap!")); } else { bFoundLightmapSample = UpdateSelectedTexel(SMComponent, -1, SMComponent->LODData[LODIndex].LightMap, ClickLocation, InterpolatedUV, LocalX, LocalY, LightmapSizeX, LightmapSizeY); } } break; } } if (!bFoundLightmapSample && Indices.Num() > 0) { const int32 SelectedTriangle = FMath::RandRange(0, Indices.Num() / 3 - 1); uint32 Index0 = Indices[SelectedTriangle]; uint32 Index1 = Indices[SelectedTriangle + 1]; uint32 Index2 = Indices[SelectedTriangle + 2]; FVector2D LightmapUV0 = LODModel.VertexBuffer.GetVertexUV(Index0, StaticMesh->LightMapCoordinateIndex); FVector2D LightmapUV1 = LODModel.VertexBuffer.GetVertexUV(Index1, StaticMesh->LightMapCoordinateIndex); FVector2D LightmapUV2 = LODModel.VertexBuffer.GetVertexUV(Index2, StaticMesh->LightMapCoordinateIndex); FVector BaryCentricWeights; BaryCentricWeights.X = FMath::FRandRange(0, 1); BaryCentricWeights.Y = FMath::FRandRange(0, 1); if (BaryCentricWeights.X + BaryCentricWeights.Y >= 1) { BaryCentricWeights.X = 1 - BaryCentricWeights.X; BaryCentricWeights.Y = 1 - BaryCentricWeights.Y; } BaryCentricWeights.Z = 1 - BaryCentricWeights.X - BaryCentricWeights.Y; FVector2D InterpolatedUV = LightmapUV0 * BaryCentricWeights.X + LightmapUV1 * BaryCentricWeights.Y + LightmapUV2 * BaryCentricWeights.Z; UE_LOG(LogStaticLightingSystem, Log, TEXT("Failed to intersect any triangles, picking random texel")); int32 PaddedSizeX = LightmapSizeX; int32 PaddedSizeY = LightmapSizeY; if (GLightmassDebugOptions.bPadMappings && GAllowLightmapPadding && LightmapSizeX - 2 > 0 && LightmapSizeY - 2 > 0) { PaddedSizeX -= 2; PaddedSizeY -= 2; } const int32 LocalX = FMath::TruncToInt(InterpolatedUV.X * PaddedSizeX); const int32 LocalY = FMath::TruncToInt(InterpolatedUV.Y * PaddedSizeY); if (LocalX < 0 || LocalX >= PaddedSizeX || LocalY < 0 || LocalY >= PaddedSizeY) { UE_LOG(LogStaticLightingSystem, Log, TEXT("Texel selection failed because the lightmap UV's wrap!")); } else { bFoundLightmapSample = UpdateSelectedTexel(SMComponent, -1, SMComponent->LODData[LODIndex].LightMap, ClickLocation, InterpolatedUV, LocalX, LocalY, LightmapSizeX, LightmapSizeY); } } } } else if (Model) { UWorld* World = Model->LightingLevel->OwningWorld; check( World); for (int32 ModelIndex = 0; ModelIndex < World->GetCurrentLevel()->ModelComponents.Num(); ModelIndex++) { UModelComponent* CurrentComponent = World->GetCurrentLevel()->ModelComponents[ModelIndex]; int32 LightmapSizeX = 0; int32 LightmapSizeY = 0; CurrentComponent->GetLightMapResolution(LightmapSizeX, LightmapSizeY); if (LightmapSizeX > 0 && LightmapSizeY > 0) { for (int32 ElementIndex = 0; ElementIndex < CurrentComponent->GetElements().Num(); ElementIndex++) { FModelElement& Element = CurrentComponent->GetElements()[ElementIndex]; TScopedPointer<FRawIndexBuffer16or32>* IndexBufferRef = Model->MaterialIndexBuffers.Find(Element.Material); check(IndexBufferRef); for(uint32 TriangleIndex = Element.FirstIndex; TriangleIndex < Element.FirstIndex + Element.NumTriangles * 3; TriangleIndex += 3) { uint32 Index0 = (*IndexBufferRef)->Indices[TriangleIndex]; uint32 Index1 = (*IndexBufferRef)->Indices[TriangleIndex + 1]; uint32 Index2 = (*IndexBufferRef)->Indices[TriangleIndex + 2]; FModelVertex* ModelVertices = (FModelVertex*)Model->VertexBuffer.Vertices.GetData(); FVector Position0 = ModelVertices[Index0].Position; FVector Position1 = ModelVertices[Index1].Position; FVector Position2 = ModelVertices[Index2].Position; FVector BaryCentricWeights; // Continue if click location is in the triangle and get its barycentric weights if (GetBarycentricWeights(Position0, Position1, Position2, ClickLocation, .001f, BaryCentricWeights)) { RestoreSelectedLightmapSample(); // Fetch lightmap UV's FVector2D LightmapUV0 = ModelVertices[Index0].ShadowTexCoord; FVector2D LightmapUV1 = ModelVertices[Index1].ShadowTexCoord; FVector2D LightmapUV2 = ModelVertices[Index2].ShadowTexCoord; // Interpolate lightmap UV's to the click location FVector2D InterpolatedUV = LightmapUV0 * BaryCentricWeights.X + LightmapUV1 * BaryCentricWeights.Y + LightmapUV2 * BaryCentricWeights.Z; // Find the node index belonging to the selected triangle const UModel* CurrentModel = CurrentComponent->GetModel(); int32 SelectedNodeIndex = INDEX_NONE; for (int32 ElementNodeIndex = 0; ElementNodeIndex < Element.Nodes.Num(); ElementNodeIndex++) { const FBspNode& CurrentNode = CurrentModel->Nodes[Element.Nodes[ElementNodeIndex]]; if ((int32)Index0 >= CurrentNode.iVertexIndex && (int32)Index0 < CurrentNode.iVertexIndex + CurrentNode.NumVertices) { SelectedNodeIndex = Element.Nodes[ElementNodeIndex]; } } check(SelectedNodeIndex >= 0); TArray<ULightComponentBase*> DummyLights; // fill out the model's NodeGroups (not the mapping part of it, but the nodes part) Model->GroupAllNodes(World->GetCurrentLevel(), DummyLights); // Find the FGatheredSurface that the selected node got put into during the last lighting rebuild TArray<int32> GatheredNodes; // find the NodeGroup that this node went into, and get all of its node for (TMap<int32, FNodeGroup*>::TIterator It(Model->NodeGroups); It && GatheredNodes.Num() == 0; ++It) { FNodeGroup* NodeGroup = It.Value(); for (int32 NodeIndex = 0; NodeIndex < NodeGroup->Nodes.Num(); NodeIndex++) { if (NodeGroup->Nodes[NodeIndex] == SelectedNodeIndex) { GatheredNodes = NodeGroup->Nodes; break; } } } check(GatheredNodes.Num() > 0); // use the surface of the selected node, it will have to suffice for the GetSurfaceLightMapResolution() call int32 SelectedGatheredSurfIndex = Model->Nodes[SelectedNodeIndex].iSurf; // Get the lightmap resolution used by the FGatheredSurface containing the selected node FMatrix WorldToMap; CurrentComponent->GetSurfaceLightMapResolution(SelectedGatheredSurfIndex, 1, LightmapSizeX, LightmapSizeY, WorldToMap, &GatheredNodes); int32 PaddedSizeX = LightmapSizeX; int32 PaddedSizeY = LightmapSizeY; if (GLightmassDebugOptions.bPadMappings && GAllowLightmapPadding && LightmapSizeX - 2 > 0 && LightmapSizeY - 2 > 0) { PaddedSizeX -= 2; PaddedSizeY -= 2; } check(LightmapSizeX > 0 && LightmapSizeY > 0); // Apply the transform to the intersection position to find the local texel coordinates const FVector4 StaticLightingTextureCoordinate = WorldToMap.TransformPosition(ClickLocation); const int32 LocalX = FMath::TruncToInt(StaticLightingTextureCoordinate.X * PaddedSizeX); const int32 LocalY = FMath::TruncToInt(StaticLightingTextureCoordinate.Y * PaddedSizeY); check(LocalX >= 0 && LocalX < PaddedSizeX && LocalY >= 0 && LocalY < PaddedSizeY); bFoundLightmapSample = UpdateSelectedTexel( CurrentComponent, SelectedNodeIndex, Element.LightMap, ClickLocation, InterpolatedUV, LocalX, LocalY, LightmapSizeX, LightmapSizeY); if (!bFoundLightmapSample) { RestoreSelectedLightmapSample(); GCurrentSelectedLightmapSample = FSelectedLightmapSample(); } return; } } } } } } if (!bFoundLightmapSample) { RestoreSelectedLightmapSample(); GCurrentSelectedLightmapSample = FSelectedLightmapSample(); } }