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;
}
Exemple #5
0
// 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

		
	}
	*/
}
Exemple #7
0
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;
	
	

}
Exemple #9
0
// 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);
		}
	}
	
}
Exemple #21
0
// 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);

	
}
Exemple #22
0
// 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();
	}
}