Beispiel #1
0
void UCheatManager::Summon( const FString& ClassName )
{
	UE_LOG(LogCheatManager, Log,  TEXT("Fabricate %s"), *ClassName );

	bool bIsValidClassName = true;
	FString FailureReason;
	if ( ClassName.Contains(TEXT(" ")) )
	{
		FailureReason = FString::Printf(TEXT("ClassName contains a space."));
		bIsValidClassName = false;
	}
	else if ( !FPackageName::IsShortPackageName(ClassName) )
	{
		if ( ClassName.Contains(TEXT(".")) )
		{
			FString PackageName;
			FString ObjectName;
			ClassName.Split(TEXT("."), &PackageName, &ObjectName);

			const bool bIncludeReadOnlyRoots = true;
			FText Reason;
			if ( !FPackageName::IsValidLongPackageName(PackageName, bIncludeReadOnlyRoots, &Reason) )
			{
				FailureReason = Reason.ToString();
				bIsValidClassName = false;
			}
		}
		else
		{
			FailureReason = TEXT("Class names with a path must contain a dot. (i.e /Script/Engine.StaticMeshActor)");
			bIsValidClassName = false;
		}
	}

	bool bSpawnedActor = false;
	if ( bIsValidClassName )
	{
		UClass* NewClass = NULL;
		if ( FPackageName::IsShortPackageName(ClassName) )
		{
			NewClass = FindObject<UClass>(ANY_PACKAGE, *ClassName);
		}
		else
		{
			NewClass = FindObject<UClass>(NULL, *ClassName);
		}

		if( NewClass )
		{
			if ( NewClass->IsChildOf(AActor::StaticClass()) )
			{
				APlayerController* const MyPlayerController = GetOuterAPlayerController();
				if(MyPlayerController)
				{
					FRotator const SpawnRot = MyPlayerController->GetControlRotation();
					FVector SpawnLoc = MyPlayerController->GetFocalLocation();

					SpawnLoc += 72.f * SpawnRot.Vector() + FVector(0.f, 0.f, 1.f) * 15.f;
					FActorSpawnParameters SpawnInfo;
					SpawnInfo.Instigator = MyPlayerController->Instigator;
					AActor* Actor = GetWorld()->SpawnActor(NewClass, &SpawnLoc, &SpawnRot, SpawnInfo );
					if ( Actor )
					{
						bSpawnedActor = true;
					}
					else
					{
						FailureReason = TEXT("SpawnActor failed.");
						bSpawnedActor = false;
					}
				}
			}
			else
			{
				FailureReason = TEXT("Class is not derived from Actor.");
				bSpawnedActor = false;
			}
		}
		else
		{
			FailureReason = TEXT("Failed to find class.");
			bSpawnedActor = false;
		}
	}
	
	if ( !bSpawnedActor )
	{
		UE_LOG(LogCheatManager, Warning, TEXT("Failed to summon %s. Reason: %s"), *ClassName, *FailureReason);
	}
}
FVector UKismetMathLibrary::Conv_FloatToVector(float InFloat)
{
	return FVector(InFloat);
}
void UKismetMathLibrary::MinimumAreaRectangle(class UObject* WorldContextObject, const TArray<FVector>& InVerts, const FVector& SampleSurfaceNormal, FVector& OutRectCenter, FRotator& OutRectRotation, float& OutSideLengthX, float& OutSideLengthY, bool bDebugDraw)
{
	float MinArea = -1.f;
	float CurrentArea = -1.f;
	FVector SupportVectorA, SupportVectorB;
	FVector RectSideA, RectSideB;
	float MinDotResultA, MinDotResultB, MaxDotResultA, MaxDotResultB;
	FVector TestEdge;
	float TestEdgeDot = 0.f;
	FVector PolyNormal(0.f, 0.f, 1.f);
	TArray<int32> PolyVertIndices;

	// Bail if we receive an empty InVerts array
	if( InVerts.Num() == 0 )
	{
		return;
	}

	// Compute the approximate normal of the poly, using the direction of SampleSurfaceNormal for guidance
	PolyNormal = (InVerts[InVerts.Num() / 3] - InVerts[0]) ^ (InVerts[InVerts.Num() * 2 / 3] - InVerts[InVerts.Num() / 3]);
	if( (PolyNormal | SampleSurfaceNormal) < 0.f )
	{
		PolyNormal = -PolyNormal;
	}

	// Transform the sample points to 2D
	FMatrix SurfaceNormalMatrix = FRotationMatrix::MakeFromZX(PolyNormal, FVector(1.f, 0.f, 0.f));
	TArray<FVector> TransformedVerts;
	OutRectCenter = FVector(0.f);
	for( int32 Idx = 0; Idx < InVerts.Num(); ++Idx )
	{
		OutRectCenter += InVerts[Idx];
		TransformedVerts.Add(SurfaceNormalMatrix.InverseTransformVector(InVerts[Idx]));
	}
	OutRectCenter /= InVerts.Num();

	// Compute the convex hull of the sample points
	ConvexHull2D::ComputeConvexHull(TransformedVerts, PolyVertIndices);

	// Minimum area rectangle as computed by http://www.geometrictools.com/Documentation/MinimumAreaRectangle.pdf
	for( int32 Idx = 1; Idx < PolyVertIndices.Num() - 1; ++Idx )
	{
		SupportVectorA = (TransformedVerts[PolyVertIndices[Idx]] - TransformedVerts[PolyVertIndices[Idx-1]]).GetSafeNormal();
		SupportVectorA.Z = 0.f;
		SupportVectorB.X = -SupportVectorA.Y;
		SupportVectorB.Y = SupportVectorA.X;
		SupportVectorB.Z = 0.f;
		MinDotResultA = MinDotResultB = MaxDotResultA = MaxDotResultB = 0.f;

		for (int TestVertIdx = 1; TestVertIdx < PolyVertIndices.Num(); ++TestVertIdx )
		{
			TestEdge = TransformedVerts[PolyVertIndices[TestVertIdx]] - TransformedVerts[PolyVertIndices[0]];
			TestEdgeDot = SupportVectorA | TestEdge;
			if( TestEdgeDot < MinDotResultA )
			{
				MinDotResultA = TestEdgeDot;
			}
			else if(TestEdgeDot > MaxDotResultA )
			{
				MaxDotResultA = TestEdgeDot;
			}

			TestEdgeDot = SupportVectorB | TestEdge;
			if( TestEdgeDot < MinDotResultB )
			{
				MinDotResultB = TestEdgeDot;
			}
			else if( TestEdgeDot > MaxDotResultB )
			{
				MaxDotResultB = TestEdgeDot;
			}
		}

		CurrentArea = (MaxDotResultA - MinDotResultA) * (MaxDotResultB - MinDotResultB);
		if( MinArea < 0.f || CurrentArea < MinArea )
		{
			MinArea = CurrentArea;
			RectSideA = SupportVectorA * (MaxDotResultA - MinDotResultA);
			RectSideB = SupportVectorB * (MaxDotResultB - MinDotResultB);
		}
	}

	RectSideA = SurfaceNormalMatrix.TransformVector(RectSideA);
	RectSideB = SurfaceNormalMatrix.TransformVector(RectSideB);
	OutRectRotation = FRotationMatrix::MakeFromZX(PolyNormal, RectSideA).Rotator();
	OutSideLengthX = RectSideA.Size();
	OutSideLengthY = RectSideB.Size();

	if( bDebugDraw )
	{
		UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject);
		if(World != nullptr)
		{
			DrawDebugSphere(World, OutRectCenter, 10.f, 12, FColor::Yellow, true);
			DrawDebugCoordinateSystem(World, OutRectCenter, SurfaceNormalMatrix.Rotator(), 100.f, true);
			DrawDebugLine(World, OutRectCenter - RectSideA * 0.5f + FVector(0,0,10.f), OutRectCenter + RectSideA * 0.5f + FVector(0,0,10.f), FColor::Green, true,-1, 0, 5.f);
			DrawDebugLine(World, OutRectCenter - RectSideB * 0.5f + FVector(0,0,10.f), OutRectCenter + RectSideB * 0.5f + FVector(0,0,10.f), FColor::Blue, true,-1, 0, 5.f);
		}
	}
}
void AJetpackItem::ClothingPress(APlayerCharacter *player) {
    player1 = player;
    isFlying = true;
    
    player->GetCharacterMovement()->AddImpulse(FVector(0, 0, 350.0f));
}
FVector UKismetMathLibrary::Conv_Vector2DToVector(FVector2D InVec2D, float Z)
{
	return FVector(InVec2D, Z);
}
AARCharacter::AARCharacter(const class FPostConstructInitializeProperties& PCIP)
	: Super(PCIP)
{
	// Set size for collision capsule
	CapsuleComponent->InitCapsuleSize(42.f, 96.0f);
	IsCharacterTurningYaw = false;
	//LowOffset = FVector(-380.0f, 35.0f, 15.0f);
	//MidOffset = FVector(-380.0f, 35.0f, 60.0f);
	//HighOffset = FVector(-380.0f, 35.0f, 150.0f); //x,y,z

	CameraBoom = PCIP.CreateDefaultSubobject<USpringArmComponent>(this, TEXT("CameraBoom"));
	CameraBoom->AttachTo(CapsuleComponent);
	CameraBoom->TargetArmLength = 300.0f; // The camera follows at this distance behind the character
	CameraBoom->bUseControllerViewRotation = true; // Rotate the arm based on the controller
	CameraBoom->SocketOffset = FVector(0.0f, 50.0f, 100.0f);
	// Create a follow camera
	FollowCamera = PCIP.CreateDefaultSubobject<UCameraComponent>(this, TEXT("FollowCamera"));
	FollowCamera->AttachTo(CameraBoom, USpringArmComponent::SocketName); // Attach the camera to the end of the boom and let the boom adjust to match the controller orientation
	FollowCamera->bUseControllerViewRotation = false; // Camera does not rotate relative to arm

	bReplicates = true;
	// Don't rotate when the controller rotates. Let that just affect the camera.
	bUseControllerRotationPitch = false;
	bUseControllerRotationYaw = true;
	bUseControllerRotationRoll = false;

	// Configure character movement
	CharacterMovement->bOrientRotationToMovement = true; // Character moves in the direction of input...	
	CharacterMovement->RotationRate = FRotator(0.0f, 540.0f, 0.0f); // ...at this rotation rate
	CharacterMovement->JumpZVelocity = 600.f;
	CharacterMovement->AirControl = 0.2f;

	Attributes = PCIP.CreateDefaultSubobject<UARAttributeComponent>(this, TEXT("Attributes"));
	Attributes->Activate();
	Attributes->bAutoRegister = true;
	Attributes->SetIsReplicated(true);

	Equipment = PCIP.CreateDefaultSubobject<UAREquipmentComponent>(this, TEXT("Equipment"));
	Equipment->Activate();
	Equipment->bAutoRegister = true;
	//Equipment->GetNetAddressable();
	Equipment->SetIsReplicated(true);

	Abilities = PCIP.CreateDefaultSubobject<UARAbilityComponent>(this, TEXT("Abilities"));
	Abilities->Activate();
	Abilities->bAutoRegister = true;
	//Equipment->GetNetAddressable();
	Abilities->SetIsReplicated(true);

	HeadMesh = PCIP.CreateDefaultSubobject<USkeletalMeshComponent>(this, TEXT("HeadMesh"));
	HeadMesh->AttachParent = Mesh;
	HeadMesh->SetMasterPoseComponent(Mesh);

	ShoulderMesh = PCIP.CreateDefaultSubobject<USkeletalMeshComponent>(this, TEXT("ShoulderMesh"));
	ShoulderMesh->AttachParent = Mesh;
	ShoulderMesh->SetMasterPoseComponent(Mesh);

	ChestMesh = PCIP.CreateDefaultSubobject<USkeletalMeshComponent>(this, TEXT("ChestMesh"));
	ChestMesh->AttachParent = Mesh;
	ChestMesh->SetMasterPoseComponent(Mesh);

	LegsMesh = PCIP.CreateDefaultSubobject<USkeletalMeshComponent>(this, TEXT("LegsMesh"));
	LegsMesh->AttachParent = Mesh;
	LegsMesh->SetMasterPoseComponent(Mesh);
	
	HandsMesh = PCIP.CreateDefaultSubobject<USkeletalMeshComponent>(this, TEXT("HandsMesh"));
	HandsMesh->AttachParent = Mesh;
	HandsMesh->SetMasterPoseComponent(Mesh);

	FootMesh = PCIP.CreateDefaultSubobject<USkeletalMeshComponent>(this, TEXT("FootMesh"));
	FootMesh->AttachParent = Mesh;
	FootMesh->SetMasterPoseComponent(Mesh);
	//SetRootComponent(Mesh);
}
Beispiel #7
0
void AWizardsCharacter::OnFire()
{
	if (!mySpellBook.IsValidIndex(0)) {
		UE_LOG(LogTemp, Warning, TEXT("Spell Gathering Needed!"));
		newCharactersSpells();
	}
	if (Mana > mySpellBook[currSpell].spellCost) {
		Mana -= mySpellBook[currSpell].spellCost;
		// try and fire a projectile

		if (mySpellBook[currSpell].spellType == 0)
		{
			const FRotator SpawnRotation = GetControlRotation();
			const FVector SpawnLocation = GetActorLocation() + SpawnRotation.RotateVector(GunOffset);

			UWorld* const World = GetWorld();
			if (World)
			{
				// spawn the projectile at the muzzle
				/*UParticleSystem* projParticle = particleList[mySpellBook[currSpell].spellEffect + mySpellBook[currSpell].spellType * 5];
				UParticleSystem* blastParticle = particleList[mySpellBook[currSpell].spellEffect + 5];
				AWizardsProjectile* wizardsSpell = World->SpawnActor<AWizardsProjectile>(ProjectileClass, SpawnLocation, SpawnRotation);// , myparams);
				wizardsSpell->SpellCreation(&mySpellBook[currSpell], projParticle, blastParticle, this);*/
				if (Role < ROLE_Authority)
				{
					ServerFireProjectile(mySpellBook[currSpell], SpawnRotation, SpawnLocation);//mySpellBook[currSpell]);
				}
				else {
					ClientFireProjectile(mySpellBook[currSpell], SpawnRotation, SpawnLocation);
				}
			}
		}
		else if (mySpellBook[currSpell].spellType == 1) {
			const FRotator SpawnRotation = FRotator(0.0);//GetControlRotation();
														 // MuzzleOffset is in camera space, so transform it to world space before offsetting from the character location to find the final muzzle position
			const FVector SpawnLocation = FVector(0.0);//GetActorLocation() + SpawnRotation.RotateVector(GunOffset);

			UWorld* const World = GetWorld();
			if (World)
			{
				// spawn the projectile at the muzzle
				/*UParticleSystem* blastParticle = particleList[mySpellBook[currSpell].spellEffect + mySpellBook[currSpell].spellType * 5];
				AWizardsBlast* wizardsSpell = World->SpawnActor<AWizardsBlast>(BlastClass, SpawnLocation, SpawnRotation);// , myparams);
				wizardsSpell->SpellCreation(blastParticle, mySpellBook[currSpell].spellSize, mySpellBook[currSpell].spellDamage, this);
				wizardsSpell->AttachRootComponentTo(GetCapsuleComponent());//Probably useful for Blasts, Rays, and Conical attacks*/
				if (Role < ROLE_Authority)
				{
					ServerFireProjectile(mySpellBook[currSpell], SpawnRotation, SpawnLocation);
				}
				else {
					ClientFireProjectile(mySpellBook[currSpell], SpawnRotation, SpawnLocation);
				}
			}
		}
		else if (mySpellBook[currSpell].spellType == 2) {
			const FRotator SpawnRotation = FRotator(0.0);//GetControlRotation();
														 // MuzzleOffset is in camera space, so transform it to world space before offsetting from the character location to find the final muzzle position
			const FVector SpawnLocation = FVector(0.0);//GetActorLocation() + SpawnRotation.RotateVector(GunOffset);

			UWorld* const World = GetWorld();
			if (World)
			{
				// spawn the projectile at the muzzle
				/*UParticleSystem* coneParticle = particleList[mySpellBook[currSpell].spellEffect + mySpellBook[currSpell].spellType * 5];
				AWizardsCone* wizardsCone = World->SpawnActor<AWizardsCone>(ConeClass, SpawnLocation, SpawnRotation);// , myparams);
				wizardsCone->SpellCreation(coneParticle, mySpellBook[currSpell].spellSize, mySpellBook[currSpell].spellDamage, this);
				wizardsCone->AttachRootComponentTo(GetCapsuleComponent());//Probably useful for Blasts, Rays, and Conical attacks
				activeAttack = Cast<AActor>(wizardsCone);*/
				if (Role < ROLE_Authority)
				{
					ServerFireProjectile(mySpellBook[currSpell], SpawnRotation, SpawnLocation);
				}
				else {
					ClientFireProjectile(mySpellBook[currSpell], SpawnRotation, SpawnLocation);
				}
			}
		}
		// God this sound is so annoying
		/*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 Pointify(const FInterpCurveVector& SplineInfo, TArray<FLandscapeSplineInterpPoint>& Points, int32 NumSubdivisions,
		float StartFalloffFraction, float EndFalloffFraction,
		const float StartWidth, const float EndWidth,
		const float StartSideFalloff, const float EndSideFalloff,
		const float StartRollDegrees, const float EndRollDegrees)
	{
		// Stop the start and end fall-off overlapping
		const float TotalFalloff = StartFalloffFraction + EndFalloffFraction;
		if (TotalFalloff > 1.0f)
		{
			StartFalloffFraction /= TotalFalloff;
			EndFalloffFraction /= TotalFalloff;
		}

		const float StartRoll = FMath::DegreesToRadians(StartRollDegrees);
		const float EndRoll = FMath::DegreesToRadians(EndRollDegrees);

		float OldKeyTime = 0;
		for (int32 i = 0; i < SplineInfo.Points.Num(); i++)
		{
			const float NewKeyTime = SplineInfo.Points[i].InVal;
			const float NewKeyCosInterp = 0.5f - 0.5f * FMath::Cos(NewKeyTime * PI);
			const float NewKeyWidth = FMath::Lerp(StartWidth, EndWidth, NewKeyCosInterp);
			const float NewKeyFalloff = FMath::Lerp(StartSideFalloff, EndSideFalloff, NewKeyCosInterp);
			const float NewKeyRoll = FMath::Lerp(StartRoll, EndRoll, NewKeyCosInterp);
			const FVector NewKeyPos = SplineInfo.Eval(NewKeyTime, FVector::ZeroVector);
			const FVector NewKeyTangent = SplineInfo.EvalDerivative(NewKeyTime, FVector::ZeroVector).GetSafeNormal();
			const FVector NewKeyBiNormal = FQuat(NewKeyTangent, -NewKeyRoll).RotateVector((NewKeyTangent ^ FVector(0, 0, -1)).GetSafeNormal());
			const FVector NewKeyLeftPos = NewKeyPos - NewKeyBiNormal * NewKeyWidth;
			const FVector NewKeyRightPos = NewKeyPos + NewKeyBiNormal * NewKeyWidth;
			const FVector NewKeyFalloffLeftPos = NewKeyPos - NewKeyBiNormal * (NewKeyWidth + NewKeyFalloff);
			const FVector NewKeyFalloffRightPos = NewKeyPos + NewKeyBiNormal * (NewKeyWidth + NewKeyFalloff);
			const float NewKeyStartEndFalloff = FMath::Min((StartFalloffFraction > 0 ? NewKeyTime / StartFalloffFraction : 1.0f), (EndFalloffFraction > 0 ? (1 - NewKeyTime) / EndFalloffFraction : 1.0f));

			// If not the first keypoint, interp from the last keypoint.
			if (i > 0)
			{
				const int32 NumSteps = FMath::CeilToInt((NewKeyTime - OldKeyTime) * NumSubdivisions);
				const float DrawSubstep = (NewKeyTime - OldKeyTime) / NumSteps;

				// Add a point for each substep, except the ends because that's the point added outside the interp'ing.
				for (int32 j = 1; j < NumSteps; j++)
				{
					const float NewTime = OldKeyTime + j*DrawSubstep;
					const float NewCosInterp = 0.5f - 0.5f * FMath::Cos(NewTime * PI);
					const float NewWidth = FMath::Lerp(StartWidth, EndWidth, NewCosInterp);
					const float NewFalloff = FMath::Lerp(StartSideFalloff, EndSideFalloff, NewCosInterp);
					const float NewRoll = FMath::Lerp(StartRoll, EndRoll, NewCosInterp);
					const FVector NewPos = SplineInfo.Eval(NewTime, FVector::ZeroVector);
					const FVector NewTangent = SplineInfo.EvalDerivative(NewTime, FVector::ZeroVector).GetSafeNormal();
					const FVector NewBiNormal = FQuat(NewTangent, -NewRoll).RotateVector((NewTangent ^ FVector(0, 0, -1)).GetSafeNormal());
					const FVector NewLeftPos = NewPos - NewBiNormal * NewWidth;
					const FVector NewRightPos = NewPos + NewBiNormal * NewWidth;
					const FVector NewFalloffLeftPos = NewPos - NewBiNormal * (NewWidth + NewFalloff);
					const FVector NewFalloffRightPos = NewPos + NewBiNormal * (NewWidth + NewFalloff);
					const float NewStartEndFalloff = FMath::Min((StartFalloffFraction > 0 ? NewTime / StartFalloffFraction : 1.0f), (EndFalloffFraction > 0 ? (1 - NewTime) / EndFalloffFraction : 1.0f));

					Points.Emplace(NewPos, NewLeftPos, NewRightPos, NewFalloffLeftPos, NewFalloffRightPos, NewStartEndFalloff);
				}
			}

			Points.Emplace(NewKeyPos, NewKeyLeftPos, NewKeyRightPos, NewKeyFalloffLeftPos, NewKeyFalloffRightPos, NewKeyStartEndFalloff);

			OldKeyTime = NewKeyTime;
		}

		// Handle self-intersection errors due to tight turns
		FixSelfIntersection(Points, &FLandscapeSplineInterpPoint::Left);
		FixSelfIntersection(Points, &FLandscapeSplineInterpPoint::Right);
		FixSelfIntersection(Points, &FLandscapeSplineInterpPoint::FalloffLeft);
		FixSelfIntersection(Points, &FLandscapeSplineInterpPoint::FalloffRight);
	}
float AWheeledVehicleAIController::CalcStreeringValue(FVector &direction)
{
  float steering = 0;
  FVector BoxExtent = Vehicle->GetVehicleBoundsExtent();
  FVector forward = Vehicle->GetActorForwardVector();

  FVector rightSensorPosition(BoxExtent.X / 2.0f, (BoxExtent.Y / 2.0f) + 100.0f, 0.0f);
  FVector leftSensorPosition(BoxExtent.X / 2.0f, -(BoxExtent.Y / 2.0f) - 100.0f, 0.0f);

  float forwardMagnitude = BoxExtent.X / 2.0f;

  float Magnitude = (float) sqrt(pow((double) leftSensorPosition.X, 2.0) + pow((double) leftSensorPosition.Y, 2.0));

  //same for the right and left
  float offset = FGenericPlatformMath::Acos(forwardMagnitude / Magnitude);

  float actorAngle = forward.UnitCartesianToSpherical().Y;

  float sinR = FGenericPlatformMath::Sin(actorAngle + offset);
  float cosR = FGenericPlatformMath::Cos(actorAngle + offset);

  float sinL = FGenericPlatformMath::Sin(actorAngle - offset);
  float cosL = FGenericPlatformMath::Cos(actorAngle - offset);

  rightSensorPosition.Y = sinR * Magnitude;
  rightSensorPosition.X = cosR * Magnitude;

  leftSensorPosition.Y = sinL * Magnitude;
  leftSensorPosition.X = cosL * Magnitude;

  FVector rightPositon = GetPawn()->GetActorLocation() + FVector(rightSensorPosition.X, rightSensorPosition.Y, 0.0f);
  FVector leftPosition = GetPawn()->GetActorLocation() + FVector(leftSensorPosition.X, leftSensorPosition.Y, 0.0f);

  FRoadMapPixelData rightRoadData = RoadMap->GetDataAt(rightPositon);
  if (!rightRoadData.IsRoad()) { steering -= 0.2f;}

  FRoadMapPixelData leftRoadData = RoadMap->GetDataAt(leftPosition);
  if (!leftRoadData.IsRoad()) { steering += 0.2f;}

  FRoadMapPixelData roadData = RoadMap->GetDataAt(GetPawn()->GetActorLocation());
  if (!roadData.IsRoad()) {
    steering = -1;
  } else if (roadData.HasDirection()) {

    direction = roadData.GetDirection();
    FVector right = rightRoadData.GetDirection();
    FVector left = leftRoadData.GetDirection();

    forward.Z = 0.0f;

    float dirAngle = direction.UnitCartesianToSpherical().Y;
    float rightAngle = right.UnitCartesianToSpherical().Y;
    float leftAngle = left.UnitCartesianToSpherical().Y;

    dirAngle *= (180.0f / PI);
    rightAngle *= (180.0 / PI);
    leftAngle *= (180.0 / PI);
    actorAngle *= (180.0 / PI);

    float min = dirAngle - 90.0f;
    if (min < -180.0f) { min = 180.0f + (min + 180.0f);}

    float max = dirAngle + 90.0f;
    if (max > 180.0f) { max = -180.0f + (max - 180.0f);}

    if (dirAngle < -90.0 || dirAngle > 90.0) {
      if (rightAngle < min && rightAngle > max) { steering -= 0.2f;}
      if (leftAngle < min && leftAngle > max) { steering += 0.2f;}
    } else {
      if (rightAngle < min || rightAngle > max) { steering -= 0.2f;}
      if (leftAngle < min || leftAngle > max) { steering += 0.2f;}
    }

    float angle = dirAngle - actorAngle;

    if (angle > 180.0f) { angle -= 360.0f;} else if (angle < -180.0f) {
      angle += 360.0f;
    }

    if (angle < -MaximumSteerAngle) {
      steering = -1.0f;
    } else if (angle > MaximumSteerAngle) {
      steering = 1.0f;
    } else {
      steering += angle / MaximumSteerAngle;
    }
  }

  Vehicle->SetAIVehicleState(ECarlaWheeledVehicleState::FreeDriving);
  return steering;
}
void RasterizeSegmentHeight(int32& MinX, int32& MinY, int32& MaxX, int32& MaxY, FLandscapeEditDataInterface& LandscapeEdit, const TArray<FLandscapeSplineInterpPoint>& Points, bool bRaiseTerrain, bool bLowerTerrain, TSet<ULandscapeComponent*>& ModifiedComponents)
{
	if (!(bRaiseTerrain || bLowerTerrain))
	{
		return;
	}

	if (MinX > MaxX || MinY > MaxY)
	{
		return;
	}

	TArray<uint16> Data;
	Data.AddZeroed((1 + MaxY - MinY) * (1 + MaxX - MinX));

	int32 ValidMinX = MinX;
	int32 ValidMinY = MinY;
	int32 ValidMaxX = MaxX;
	int32 ValidMaxY = MaxY;
	LandscapeEdit.GetHeightData(ValidMinX, ValidMinY, ValidMaxX, ValidMaxY, Data.GetData(), 0);

	if (ValidMinX > ValidMaxX || ValidMinY > ValidMaxY)
	{
		// The segment's bounds don't intersect any data, so skip it
		MinX = ValidMinX;
		MinY = ValidMinY;
		MaxX = ValidMaxX;
		MaxY = ValidMaxY;

		return;
	}

	FLandscapeEditDataInterface::ShrinkData(Data, MinX, MinY, MaxX, MaxY, ValidMinX, ValidMinY, ValidMaxX, ValidMaxY);

	MinX = ValidMinX;
	MinY = ValidMinY;
	MaxX = ValidMaxX;
	MaxY = ValidMaxY;

	FTriangleRasterizer<FLandscapeSplineHeightsRasterPolicy> Rasterizer(
		FLandscapeSplineHeightsRasterPolicy(Data, MinX, MinY, MaxX, MaxY, bRaiseTerrain, bLowerTerrain));

	for (int32 j = 1; j < Points.Num(); j++)
	{
		// Middle
		FVector2D Left0Pos = FVector2D(Points[j - 1].Left);
		FVector2D Right0Pos = FVector2D(Points[j - 1].Right);
		FVector2D Left1Pos = FVector2D(Points[j].Left);
		FVector2D Right1Pos = FVector2D(Points[j].Right);
		FVector Left0 = FVector(1.0f, Points[j - 1].StartEndFalloff, Points[j - 1].Left.Z);
		FVector Right0 = FVector(1.0f, Points[j - 1].StartEndFalloff, Points[j - 1].Right.Z);
		FVector Left1 = FVector(1.0f, Points[j].StartEndFalloff, Points[j].Left.Z);
		FVector Right1 = FVector(1.0f, Points[j].StartEndFalloff, Points[j].Right.Z);
		Rasterizer.DrawTriangle(Left0, Right0, Left1, Left0Pos, Right0Pos, Left1Pos, false);
		Rasterizer.DrawTriangle(Right0, Left1, Right1, Right0Pos, Left1Pos, Right1Pos, false);

		// Left Falloff
		FVector2D FalloffLeft0Pos = FVector2D(Points[j - 1].FalloffLeft);
		FVector2D FalloffLeft1Pos = FVector2D(Points[j].FalloffLeft);
		FVector FalloffLeft0 = FVector(0.0f, Points[j - 1].StartEndFalloff, Points[j - 1].FalloffLeft.Z);
		FVector FalloffLeft1 = FVector(0.0f, Points[j].StartEndFalloff, Points[j].FalloffLeft.Z);
		Rasterizer.DrawTriangle(FalloffLeft0, Left0, FalloffLeft1, FalloffLeft0Pos, Left0Pos, FalloffLeft1Pos, false);
		Rasterizer.DrawTriangle(Left0, FalloffLeft1, Left1, Left0Pos, FalloffLeft1Pos, Left1Pos, false);

		// Right Falloff
		FVector2D FalloffRight0Pos = FVector2D(Points[j - 1].FalloffRight);
		FVector2D FalloffRight1Pos = FVector2D(Points[j].FalloffRight);
		FVector FalloffRight0 = FVector(0.0f, Points[j - 1].StartEndFalloff, Points[j - 1].FalloffRight.Z);
		FVector FalloffRight1 = FVector(0.0f, Points[j].StartEndFalloff, Points[j].FalloffRight.Z);
		Rasterizer.DrawTriangle(Right0, FalloffRight0, Right1, Right0Pos, FalloffRight0Pos, Right1Pos, false);
		Rasterizer.DrawTriangle(FalloffRight0, Right1, FalloffRight1, FalloffRight0Pos, Right1Pos, FalloffRight1Pos, false);
	}

	LandscapeEdit.SetHeightData(MinX, MinY, MaxX, MaxY, Data.GetData(), 0, true);
	LandscapeEdit.GetComponentsInRegion(MinX, MinY, MaxX, MaxY, &ModifiedComponents);
}
void RasterizeSegmentAlpha(int32& MinX, int32& MinY, int32& MaxX, int32& MaxY, FLandscapeEditDataInterface& LandscapeEdit, const TArray<FLandscapeSplineInterpPoint>& Points, ULandscapeLayerInfoObject* LayerInfo, TSet<ULandscapeComponent*>& ModifiedComponents)
{
	if (LayerInfo == nullptr)
	{
		return;
	}

	if (MinX > MaxX || MinY > MaxY)
	{
		return;
	}

	TArray<uint8> Data;
	Data.AddZeroed((1 + MaxY - MinY) * (1 + MaxX - MinX));

	int32 ValidMinX = MinX;
	int32 ValidMinY = MinY;
	int32 ValidMaxX = MaxX;
	int32 ValidMaxY = MaxY;
	LandscapeEdit.GetWeightData(LayerInfo, ValidMinX, ValidMinY, ValidMaxX, ValidMaxY, Data.GetData(), 0);

	if (ValidMinX > ValidMaxX || ValidMinY > ValidMaxY)
	{
		// The segment's bounds don't intersect any data, so skip it
		MinX = ValidMinX;
		MinY = ValidMinY;
		MaxX = ValidMaxX;
		MaxY = ValidMaxY;

		return;
	}

	FLandscapeEditDataInterface::ShrinkData(Data, MinX, MinY, MaxX, MaxY, ValidMinX, ValidMinY, ValidMaxX, ValidMaxY);

	MinX = ValidMinX;
	MinY = ValidMinY;
	MaxX = ValidMaxX;
	MaxY = ValidMaxY;

	FTriangleRasterizer<FLandscapeSplineBlendmaskRasterPolicy> Rasterizer(
		FLandscapeSplineBlendmaskRasterPolicy(Data, MinX, MinY, MaxX, MaxY));

	const float BlendValue = 255;

	for (int32 j = 1; j < Points.Num(); j++)
	{
		// Middle
		FVector2D Left0Pos = FVector2D(Points[j - 1].Left);
		FVector2D Right0Pos = FVector2D(Points[j - 1].Right);
		FVector2D Left1Pos = FVector2D(Points[j].Left);
		FVector2D Right1Pos = FVector2D(Points[j].Right);
		FVector Left0 = FVector(1.0f, Points[j - 1].StartEndFalloff, BlendValue);
		FVector Right0 = FVector(1.0f, Points[j - 1].StartEndFalloff, BlendValue);
		FVector Left1 = FVector(1.0f, Points[j].StartEndFalloff, BlendValue);
		FVector Right1 = FVector(1.0f, Points[j].StartEndFalloff, BlendValue);
		Rasterizer.DrawTriangle(Left0, Right0, Left1, Left0Pos, Right0Pos, Left1Pos, false);
		Rasterizer.DrawTriangle(Right0, Left1, Right1, Right0Pos, Left1Pos, Right1Pos, false);

		// Left Falloff
		FVector2D FalloffLeft0Pos = FVector2D(Points[j - 1].FalloffLeft);
		FVector2D FalloffLeft1Pos = FVector2D(Points[j].FalloffLeft);
		FVector FalloffLeft0 = FVector(0.0f, Points[j - 1].StartEndFalloff, BlendValue);
		FVector FalloffLeft1 = FVector(0.0f, Points[j].StartEndFalloff, BlendValue);
		Rasterizer.DrawTriangle(FalloffLeft0, Left0, FalloffLeft1, FalloffLeft0Pos, Left0Pos, FalloffLeft1Pos, false);
		Rasterizer.DrawTriangle(Left0, FalloffLeft1, Left1, Left0Pos, FalloffLeft1Pos, Left1Pos, false);

		// Right Falloff
		FVector2D FalloffRight0Pos = FVector2D(Points[j - 1].FalloffRight);
		FVector2D FalloffRight1Pos = FVector2D(Points[j].FalloffRight);
		FVector FalloffRight0 = FVector(0.0f, Points[j - 1].StartEndFalloff, BlendValue);
		FVector FalloffRight1 = FVector(0.0f, Points[j].StartEndFalloff, BlendValue);
		Rasterizer.DrawTriangle(Right0, FalloffRight0, Right1, Right0Pos, FalloffRight0Pos, Right1Pos, false);
		Rasterizer.DrawTriangle(FalloffRight0, Right1, FalloffRight1, FalloffRight0Pos, Right1Pos, FalloffRight1Pos, false);
	}

	LandscapeEdit.SetAlphaData(LayerInfo, MinX, MinY, MaxX, MaxY, Data.GetData(), 0, ELandscapeLayerPaintingRestriction::None, !LayerInfo->bNoWeightBlend, false);
	LandscapeEdit.GetComponentsInRegion(MinX, MinY, MaxX, MaxY, &ModifiedComponents);
}
void RasterizeControlPointHeights(int32& MinX, int32& MinY, int32& MaxX, int32& MaxY, FLandscapeEditDataInterface& LandscapeEdit, FVector ControlPointLocation, const TArray<FLandscapeSplineInterpPoint>& Points, bool bRaiseTerrain, bool bLowerTerrain, TSet<ULandscapeComponent*>& ModifiedComponents)
{
	if (!(bRaiseTerrain || bLowerTerrain))
	{
		return;
	}

	if (MinX > MaxX || MinY > MaxY)
	{
		return;
	}

	TArray<uint16> Data;
	Data.AddZeroed((1 + MaxY - MinY) * (1 + MaxX - MinX));

	int32 ValidMinX = MinX;
	int32 ValidMinY = MinY;
	int32 ValidMaxX = MaxX;
	int32 ValidMaxY = MaxY;
	LandscapeEdit.GetHeightData(ValidMinX, ValidMinY, ValidMaxX, ValidMaxY, Data.GetData(), 0);

	if (ValidMinX > ValidMaxX || ValidMinY > ValidMaxY)
	{
		// The control point's bounds don't intersect any data, so skip it
		MinX = ValidMinX;
		MinY = ValidMinY;
		MaxX = ValidMaxX;
		MaxY = ValidMaxY;

		return;
	}

	FLandscapeEditDataInterface::ShrinkData(Data, MinX, MinY, MaxX, MaxY, ValidMinX, ValidMinY, ValidMaxX, ValidMaxY);

	MinX = ValidMinX;
	MinY = ValidMinY;
	MaxX = ValidMaxX;
	MaxY = ValidMaxY;

	FTriangleRasterizer<FLandscapeSplineHeightsRasterPolicy> Rasterizer(
		FLandscapeSplineHeightsRasterPolicy(Data, MinX, MinY, MaxX, MaxY, bRaiseTerrain, bLowerTerrain));

	const FVector2D CenterPos = FVector2D(ControlPointLocation);
	const FVector Center = FVector(1.0f, Points[0].StartEndFalloff, ControlPointLocation.Z * LANDSCAPE_INV_ZSCALE + LandscapeDataAccess::MidValue);

	for (int32 i = Points.Num() - 1, j = 0; j < Points.Num(); i = j++)
	{
		// Solid center
		const FVector2D Right0Pos = FVector2D(Points[i].Right);
		const FVector2D Left1Pos = FVector2D(Points[j].Left);
		const FVector2D Right1Pos = FVector2D(Points[j].Right);
		const FVector Right0 = FVector(1.0f, Points[i].StartEndFalloff, Points[i].Right.Z);
		const FVector Left1 = FVector(1.0f, Points[j].StartEndFalloff, Points[j].Left.Z);
		const FVector Right1 = FVector(1.0f, Points[j].StartEndFalloff, Points[j].Right.Z);

		Rasterizer.DrawTriangle(Center, Right0, Left1, CenterPos, Right0Pos, Left1Pos, false);
		Rasterizer.DrawTriangle(Center, Left1, Right1, CenterPos, Left1Pos, Right1Pos, false);

		// Falloff
		FVector2D FalloffRight0Pos = FVector2D(Points[i].FalloffRight);
		FVector2D FalloffLeft1Pos = FVector2D(Points[j].FalloffLeft);
		FVector FalloffRight0 = FVector(0.0f, Points[i].StartEndFalloff, Points[i].FalloffRight.Z);
		FVector FalloffLeft1 = FVector(0.0f, Points[j].StartEndFalloff, Points[j].FalloffLeft.Z);
		Rasterizer.DrawTriangle(Right0, FalloffRight0, Left1, Right0Pos, FalloffRight0Pos, Left1Pos, false);
		Rasterizer.DrawTriangle(FalloffRight0, Left1, FalloffLeft1, FalloffRight0Pos, Left1Pos, FalloffLeft1Pos, false);
	}

	LandscapeEdit.SetHeightData(MinX, MinY, MaxX, MaxY, Data.GetData(), 0, true);
	LandscapeEdit.GetComponentsInRegion(MinX, MinY, MaxX, MaxY, &ModifiedComponents);
}
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);
	}
}
FPhATEdPreviewViewportClient::FPhATEdPreviewViewportClient(TWeakPtr<FPhAT> InPhAT, TSharedPtr<FPhATSharedData> Data, const TSharedRef<SPhATPreviewViewport>& InPhATPreviewViewport)
	: FEditorViewportClient(nullptr, &Data->PreviewScene, StaticCastSharedRef<SEditorViewport>(InPhATPreviewViewport))
	, PhATPtr(InPhAT)
	, SharedData(Data)
	, MinPrimSize(0.5f)
	, PhAT_TranslateSpeed(0.25f)
	, PhAT_RotateSpeed(1.0 * (PI / 180.0))
	, PhAT_LightRotSpeed(0.22f)
	, SimGrabCheckDistance(5000.0f)
	, SimHoldDistanceChangeDelta(20.0f)
	, SimMinHoldDistance(10.0f)
	, SimGrabMoveSpeed(1.0f)
{
	check(PhATPtr.IsValid());

	ModeTools->SetWidgetMode(FWidget::EWidgetMode::WM_Translate);
	ModeTools->SetCoordSystem(COORD_Local);

	bAllowedToMoveCamera = true;

	// Setup defaults for the common draw helper.
	DrawHelper.bDrawPivot = false;
	DrawHelper.bDrawWorldBox = false;
	DrawHelper.bDrawKillZ = false;
	DrawHelper.GridColorAxis = FColor(80,80,80);
	DrawHelper.GridColorMajor = FColor(72,72,72);
	DrawHelper.GridColorMinor = FColor(64,64,64);
	DrawHelper.PerspectiveGridSize = 32767;

	PhATFont = GEngine->GetSmallFont();
	check(PhATFont);

	EngineShowFlags.DisableAdvancedFeatures();
	EngineShowFlags.SetSeparateTranslucency(true);
	EngineShowFlags.SetCompositeEditorPrimitives(true);

	// Get actors asset collision bounding box, and move actor so its not intersection the floor plane at Z = 0.
	FBox CollBox = SharedData->PhysicsAsset->CalcAABB(SharedData->EditorSkelComp, SharedData->EditorSkelComp->ComponentToWorld);	
	FVector SkelCompLocation = FVector(0, 0, -CollBox.Min.Z + SharedData->EditorSimOptions->FloorGap);

	SharedData->EditorSkelComp->SetAbsolute(true, true, true);
	SharedData->EditorSkelComp->SetRelativeLocation(SkelCompLocation);
	SharedData->ResetTM = SharedData->EditorSkelComp->GetComponentToWorld();

	// Get new bounding box and set view based on that.
	CollBox = SharedData->PhysicsAsset->CalcAABB(SharedData->EditorSkelComp, SharedData->EditorSkelComp->ComponentToWorld);	
	FVector CollBoxExtent = CollBox.GetExtent();

	// Take into account internal mesh translation/rotation/scaling etc.
	FTransform LocalToWorld = SharedData->EditorSkelComp->ComponentToWorld;
	FSphere WorldSphere = SharedData->EditorSkelMesh->GetImportedBounds().GetSphere().TransformBy(LocalToWorld);

	CollBoxExtent = CollBox.GetExtent();
	if (CollBoxExtent.X > CollBoxExtent.Y)
	{
		SetViewLocation( FVector(WorldSphere.Center.X, WorldSphere.Center.Y - 1.5*WorldSphere.W, WorldSphere.Center.Z) );
		SetViewRotation( EditorViewportDefs::DefaultPerspectiveViewRotation );	
	}
	else
	{
		SetViewLocation( FVector(WorldSphere.Center.X - 1.5*WorldSphere.W, WorldSphere.Center.Y, WorldSphere.Center.Z) );
		SetViewRotation( FRotator::ZeroRotator );	
	}
	
	SetViewLocationForOrbiting(FVector::ZeroVector);

	SetViewModes(VMI_Lit, VMI_Lit);

	SetCameraSpeedSetting(3);

	bUsingOrbitCamera = true;

	if (!FPhAT::IsPIERunning())
	{
		SetRealtime(true);
	}
}
Beispiel #15
0
FVector ULeapImage::Warp(FVector xy) const
{
	Leap::Vector vect = Leap::Vector(xy.X, xy.Y, xy.Z);
	vect = _private->leapImage.warp(vect);
	return FVector(vect.x, vect.y, vect.z);
}
FVector ADraggableMoveTile::calculateCurrentDir()
{
	auto startNode = path[currNode];
	return FVector();
}
Beispiel #17
0
FVector PrivateLeapImage::FindBlob(const int32 SrcWidth, const int32 SrcHeight, int32 Start, std::vector<uint8>& checkPixel, int32 Stack, uint8* imageBuffer, int* stackLimit, const uint8 brightnessThresholdIn, const uint8 brightnessThresholdOut)
{
	float weight, sum;
	FVector pos, nPos;
	uint8* SrcPtr = NULL;
	uint8 Value;
	if (pixelsFound > pixelLimit) *stackLimit = 2;
	if (Stack >= 100) *stackLimit = 0;
	if (*stackLimit == 1) {

		Leap::Vector Dir = leapImage.rectify(Leap::Vector(floor(Start%SrcWidth), floor(Start / SrcWidth), 0.0f));
		//		Leap::Vector Dir = Leap::Vector(floor(Start%SrcWidth), floor(Start / SrcWidth), 0.0f);

		SrcPtr = (&imageBuffer[Start]);
		Value = *SrcPtr;
		weight = pow((float)(Value - brightnessThresholdOut), 2) + 1.f;
		//		weight = (float)(Value - brightnessThresholdOut) + 0.01f;
		pos = FVector(Dir.x * weight, Dir.y * weight, 0.0f);
		sum = weight;
		checkPixel[Start] = 1;
		pixelsFound++;
		//		if (Stack >= 15) *stackLimit = 0;
		//		ASSIMILATE THE SURROUNDING PIXELS
		//		if (Stack < 15) {//PREVENTS STACK OVERFLOW

		SrcPtr = (&imageBuffer[Start - 1]);
		Value = *SrcPtr;
		if ((floor(Start % SrcWidth) != 0) && (Value > brightnessThresholdOut) && (*stackLimit == 1)) if (checkPixel[Start - 1] == 0) {
			nPos = FindBlob(SrcWidth, SrcHeight, Start - 1, checkPixel, Stack + 1, imageBuffer, stackLimit, brightnessThresholdIn, brightnessThresholdOut);
			pos = FVector(pos.X + nPos.X, pos.Y + nPos.Y, 0.0f);
			if (nPos == FVector(0.0f, 0.0f, 0.0f)) *stackLimit = 0;
			sum += nPos.Z;
		}
		SrcPtr = (&imageBuffer[Start + 1]);
		Value = *SrcPtr;
		if ((floor(Start % SrcWidth) != SrcWidth - 1) && (Value > brightnessThresholdOut) && (*stackLimit == 1)) if (checkPixel[Start + 1] == 0) {
			nPos = FindBlob(SrcWidth, SrcHeight, Start + 1, checkPixel, Stack + 1, imageBuffer, stackLimit, brightnessThresholdIn, brightnessThresholdOut);
			pos = FVector(pos.X + nPos.X, pos.Y + nPos.Y, 0.0f);
			if (nPos == FVector(0.0f, 0.0f, 0.0f)) *stackLimit = 0;
			sum += nPos.Z;
		}
		SrcPtr = (&imageBuffer[Start - SrcWidth]);
		Value = *SrcPtr;
		if ((floor(Start / SrcWidth) != 0) && (Value > brightnessThresholdOut) && (*stackLimit == 1)) if (checkPixel[Start - SrcWidth] == 0) {
			nPos = FindBlob(SrcWidth, SrcHeight, Start - SrcWidth, checkPixel, Stack + 1, imageBuffer, stackLimit, brightnessThresholdIn, brightnessThresholdOut);
			pos = FVector(pos.X + nPos.X, pos.Y + nPos.Y, 0.0f);
			if (nPos == FVector(0.0f, 0.0f, 0.0f)) *stackLimit = 0;
			sum += nPos.Z;
		}
		SrcPtr = (&imageBuffer[Start + SrcWidth]);
		Value = *SrcPtr;
		if ((floor(Start / SrcWidth) != SrcHeight - 1) && (Value > brightnessThresholdOut) && (*stackLimit == 1)) if (checkPixel[Start + SrcWidth] == 0) {
			nPos = FindBlob(SrcWidth, SrcHeight, Start + SrcWidth, checkPixel, Stack + 1, imageBuffer, stackLimit, brightnessThresholdIn, brightnessThresholdOut);
			pos = FVector(pos.X + nPos.X, pos.Y + nPos.Y, 0.0f);
			if (nPos == FVector(0.0f, 0.0f, 0.0f)) *stackLimit = 0;
			sum += nPos.Z;
		}
	}

	if (*stackLimit == 1)
		return FVector(pos.X, pos.Y, sum);
	else
		return FVector(0.0f, 0.0f, 0.0f);

	//	return FVector(1.0f, 1.0f, 1.0f);
}
void ASimpleCylinderActor::GenerateCylinder(TArray<FRuntimeMeshVertexSimple>& InVertices, TArray<int32>& InTriangles, float InHeight, float InWidth, int32 InCrossSectionCount, bool bInCapEnds, bool bInDoubleSided, bool bInSmoothNormals/* = true*/)
{
	// -------------------------------------------------------
	// Basic setup
	int32 VertexIndex = 0;
	int32 TriangleIndex = 0;

	// -------------------------------------------------------
	// Make a cylinder section
	const float AngleBetweenQuads = (2.0f / (float)(InCrossSectionCount)) * PI;
	const float VMapPerQuad = 1.0f / (float)InCrossSectionCount;
	FVector Offset = FVector(0, 0, InHeight);

	// Start by building up vertices that make up the cylinder sides
	for (int32 QuadIndex = 0; QuadIndex < InCrossSectionCount; QuadIndex++)
	{
		float Angle = (float)QuadIndex * AngleBetweenQuads;
		float NextAngle = (float)(QuadIndex + 1) * AngleBetweenQuads;

		// Set up the vertices
		FVector p0 = FVector(FMath::Cos(Angle) * InWidth, FMath::Sin(Angle) * InWidth, 0.f);
		FVector p1 = FVector(FMath::Cos(NextAngle) * InWidth, FMath::Sin(NextAngle) * InWidth, 0.f);
		FVector p2 = p1 + Offset;
		FVector p3 = p0 + Offset;

		// Set up the quad triangles
		int32 VertIndex1 = VertexIndex++;
		int32 VertIndex2 = VertexIndex++;
		int32 VertIndex3 = VertexIndex++;
		int32 VertIndex4 = VertexIndex++;

		InVertices[VertIndex1].Position = p0;
		InVertices[VertIndex2].Position = p1;
		InVertices[VertIndex3].Position = p2;
		InVertices[VertIndex4].Position = p3;

		// Now create two triangles from those four vertices
		// The order of these (clockwise/counter-clockwise) dictates which way the normal will face. 
		InTriangles[TriangleIndex++] = VertIndex4;
		InTriangles[TriangleIndex++] = VertIndex3;
		InTriangles[TriangleIndex++] = VertIndex1;

		InTriangles[TriangleIndex++] = VertIndex3;
		InTriangles[TriangleIndex++] = VertIndex2;
		InTriangles[TriangleIndex++] = VertIndex1;

		// UVs.  Note that Unreal UV origin (0,0) is top left
		InVertices[VertIndex1].UV0 = FVector2D(1.0f - (VMapPerQuad * QuadIndex), 1.0f);
		InVertices[VertIndex2].UV0 = FVector2D(1.0f - (VMapPerQuad * (QuadIndex + 1)), 1.0f);
		InVertices[VertIndex3].UV0 = FVector2D(1.0f - (VMapPerQuad * (QuadIndex + 1)), 0.0f);
		InVertices[VertIndex4].UV0 = FVector2D(1.0f - (VMapPerQuad * QuadIndex), 0.0f);

		// Normals
		FVector NormalCurrent = FVector::CrossProduct(InVertices[VertIndex1].Position - InVertices[VertIndex3].Position, InVertices[VertIndex2].Position - InVertices[VertIndex3].Position).GetSafeNormal();

		if (bInSmoothNormals)
		{
			// To smooth normals we give the vertices different values than the polygon they belong to.
			// GPUs know how to interpolate between those.
			// I do this here as an average between normals of two adjacent polygons
			float NextNextAngle = (float)(QuadIndex + 2) * AngleBetweenQuads;
			FVector p4 = FVector(FMath::Cos(NextNextAngle) * InWidth, FMath::Sin(NextNextAngle) * InWidth, 0.f);

			// p1 to p4 to p2
			FVector NormalNext = FVector::CrossProduct(p1 - p2, p4 - p2).GetSafeNormal();
			FVector AverageNormalRight = (NormalCurrent + NormalNext) / 2;
			AverageNormalRight = AverageNormalRight.GetSafeNormal();

			float PreviousAngle = (float)(QuadIndex - 1) * AngleBetweenQuads;
			FVector pMinus1 = FVector(FMath::Cos(PreviousAngle) * InWidth, FMath::Sin(PreviousAngle) * InWidth, 0.f);

			// p0 to p3 to pMinus1
			FVector NormalPrevious = FVector::CrossProduct(p0 - pMinus1, p3 - pMinus1).GetSafeNormal();
			FVector AverageNormalLeft = (NormalCurrent + NormalPrevious) / 2;
			AverageNormalLeft = AverageNormalLeft.GetSafeNormal();

			InVertices[VertIndex1].Normal = FPackedNormal(AverageNormalLeft);
			InVertices[VertIndex2].Normal = FPackedNormal(AverageNormalRight);
			InVertices[VertIndex3].Normal = FPackedNormal(AverageNormalRight);
			InVertices[VertIndex4].Normal = FPackedNormal(AverageNormalLeft);
		}
		else
		{
			// If not smoothing we just set the vertex normal to the same normal as the polygon they belong to
			InVertices[VertIndex1].Normal = InVertices[VertIndex2].Normal = InVertices[VertIndex3].Normal = InVertices[VertIndex4].Normal = FPackedNormal(NormalCurrent);
		}

		// Tangents (perpendicular to the surface)
		FVector SurfaceTangent = p0 - p1;
		SurfaceTangent = SurfaceTangent.GetSafeNormal();
		InVertices[VertIndex1].Tangent = InVertices[VertIndex2].Tangent = InVertices[VertIndex3].Tangent = InVertices[VertIndex4].Tangent = FPackedNormal(SurfaceTangent);

		// -------------------------------------------------------
		// If double sided, create extra polygons but face the normals the other way.
		if (bInDoubleSided)
		{
			VertIndex1 = VertexIndex++;
			VertIndex2 = VertexIndex++;
			VertIndex3 = VertexIndex++;
			VertIndex4 = VertexIndex++;

			InVertices[VertIndex1].Position = p0;
			InVertices[VertIndex2].Position = p1;
			InVertices[VertIndex3].Position = p2;
			InVertices[VertIndex4].Position = p3;

			// Reverse the poly order to face them the other way
			InTriangles[TriangleIndex++] = VertIndex4;
			InTriangles[TriangleIndex++] = VertIndex1;
			InTriangles[TriangleIndex++] = VertIndex3;

			InTriangles[TriangleIndex++] = VertIndex3;
			InTriangles[TriangleIndex++] = VertIndex1;
			InTriangles[TriangleIndex++] = VertIndex2;

			// UVs  (Unreal 1,1 is top left)
			InVertices[VertIndex1].UV0 = FVector2D(1.0f - (VMapPerQuad * QuadIndex), 1.0f);
			InVertices[VertIndex2].UV0 = FVector2D(1.0f - (VMapPerQuad * (QuadIndex + 1)), 1.0f);
			InVertices[VertIndex3].UV0 = FVector2D(1.0f - (VMapPerQuad * (QuadIndex + 1)), 0.0f);
			InVertices[VertIndex4].UV0 = FVector2D(1.0f - (VMapPerQuad * QuadIndex), 0.0f);

			// Just simple (unsmoothed) normal for these
			InVertices[VertIndex1].Normal = InVertices[VertIndex2].Normal = InVertices[VertIndex3].Normal = InVertices[VertIndex4].Normal = FPackedNormal(NormalCurrent);

			// Tangents (perpendicular to the surface)
			FVector SurfaceTangentDbl = p0 - p1;
			SurfaceTangentDbl = SurfaceTangentDbl.GetSafeNormal();
			InVertices[VertIndex1].Tangent = InVertices[VertIndex2].Tangent = InVertices[VertIndex3].Tangent = InVertices[VertIndex4].Tangent = FPackedNormal(SurfaceTangentDbl);
		}

		// -------------------------------------------------------
		// Caps are closed here by triangles that start at 0, then use the points along the circle for the other two corners.
		// A better looking method uses a vertex in the center of the circle, but uses two more polygons.  We will demonstrate that in a different sample.
		if (QuadIndex != 0 && QuadIndex != InCrossSectionCount - 1 && bInCapEnds)
		{
			// Bottom cap
			FVector capVertex0 = FVector(FMath::Cos(0) * InWidth, FMath::Sin(0) * InWidth, 0.f);
			FVector capVertex1 = FVector(FMath::Cos(Angle) * InWidth, FMath::Sin(Angle) * InWidth, 0.f);
			FVector capVertex2 = FVector(FMath::Cos(NextAngle) * InWidth, FMath::Sin(NextAngle) * InWidth, 0.f);

			VertIndex1 = VertexIndex++;
			VertIndex2 = VertexIndex++;
			VertIndex3 = VertexIndex++;
			InVertices[VertIndex1].Position = capVertex0;
			InVertices[VertIndex2].Position = capVertex1;
			InVertices[VertIndex3].Position = capVertex2;

			InTriangles[TriangleIndex++] = VertIndex1;
			InTriangles[TriangleIndex++] = VertIndex2;
			InTriangles[TriangleIndex++] = VertIndex3;

			InVertices[VertIndex1].UV0 = FVector2D(0.5f - (FMath::Cos(0) / 2.0f), 0.5f - (FMath::Sin(0) / 2.0f));
			InVertices[VertIndex2].UV0 = FVector2D(0.5f - (FMath::Cos(-Angle) / 2.0f), 0.5f - (FMath::Sin(-Angle) / 2.0f));
			InVertices[VertIndex3].UV0 = FVector2D(0.5f - (FMath::Cos(-NextAngle) / 2.0f), 0.5f - (FMath::Sin(-NextAngle) / 2.0f));

			FVector CapNormalCurrent = FVector::CrossProduct(InVertices[VertIndex1].Position - InVertices[VertIndex3].Position, InVertices[VertIndex2].Position - InVertices[VertIndex3].Position).GetSafeNormal();
			InVertices[VertIndex1].Normal = InVertices[VertIndex2].Normal = InVertices[VertIndex3].Normal = FPackedNormal(CapNormalCurrent);

			// Tangents (perpendicular to the surface)
			FVector SurfaceTangentCap = p0 - p1;
			SurfaceTangentCap = SurfaceTangentCap.GetSafeNormal();
			InVertices[VertIndex1].Tangent = InVertices[VertIndex2].Tangent = InVertices[VertIndex3].Tangent = FPackedNormal(SurfaceTangentCap);

			// Top cap
			capVertex0 = capVertex0 + Offset;
			capVertex1 = capVertex1 + Offset;
			capVertex2 = capVertex2 + Offset;

			VertIndex1 = VertexIndex++;
			VertIndex2 = VertexIndex++;
			VertIndex3 = VertexIndex++;
			InVertices[VertIndex1].Position = capVertex0;
			InVertices[VertIndex2].Position = capVertex1;
			InVertices[VertIndex3].Position = capVertex2;

			InTriangles[TriangleIndex++] = VertIndex3;
			InTriangles[TriangleIndex++] = VertIndex2;
			InTriangles[TriangleIndex++] = VertIndex1;

			InVertices[VertIndex1].UV0 = FVector2D(0.5f - (FMath::Cos(0) / 2.0f), 0.5f - (FMath::Sin(0) / 2.0f));
			InVertices[VertIndex2].UV0 = FVector2D(0.5f - (FMath::Cos(Angle) / 2.0f), 0.5f - (FMath::Sin(Angle) / 2.0f));
			InVertices[VertIndex3].UV0 = FVector2D(0.5f - (FMath::Cos(NextAngle) / 2.0f), 0.5f - (FMath::Sin(NextAngle) / 2.0f));

			CapNormalCurrent = FVector::CrossProduct(InVertices[VertIndex1].Position - InVertices[VertIndex3].Position, InVertices[VertIndex2].Position - InVertices[VertIndex3].Position).GetSafeNormal();
			InVertices[VertIndex1].Normal = InVertices[VertIndex2].Normal = InVertices[VertIndex3].Normal = FPackedNormal(CapNormalCurrent);

			// Tangents (perpendicular to the surface)
			SurfaceTangentCap = p0 - p1;
			SurfaceTangentCap = SurfaceTangentCap.GetSafeNormal();
			InVertices[VertIndex1].Tangent = InVertices[VertIndex2].Tangent = InVertices[VertIndex3].Tangent = FPackedNormal(SurfaceTangentCap);
		}
	}
}
Beispiel #19
0
AWizardsCharacter::AWizardsCharacter()
{
	bReplicates = true;
	//Tick for mana regen
	PrimaryActorTick.bCanEverTick = true;
	//Set Health and Mana
	Health = 100.0;
	maxHealth = 100.0;
	Mana = 100.0;
	maxMana = 100.0;
	//Spell Stuff for Testing
	//SList.spellCost = 10.0;

	ConstructorHelpers::FObjectFinder<UParticleSystem> ArbitraryParticleName(TEXT("ParticleSystem'/Game/StarterContent/Particles/P_Sparks.P_Sparks'"));
	//SList.myParticle = ArbitraryParticleName.Object;
	//SList.test = &ArbitraryParticleName;
	currSpell = 0;
	//For the record, this probably isn't the best way to get particles for the spells but it works
	//A better method, implemented at a later and unknown date, would be to hold this array in its own class
	//that is called once and never destroyed
	//Projectiles
	ConstructorHelpers::FObjectFinder<UParticleSystem> ArbitraryParticleName0(TEXT("ParticleSystem'/Game/FirstPerson/Particles/P_Fire_Projectile.P_Fire_Projectile'"));
	particleList.Add(ArbitraryParticleName0.Object);
	ConstructorHelpers::FObjectFinder<UParticleSystem> ArbitraryParticleName1(TEXT("ParticleSystem'/Game/FirstPerson/Particles/P_Lightning_Projectile.P_Lightning_Projectile'"));
	particleList.Add(ArbitraryParticleName1.Object);
	ConstructorHelpers::FObjectFinder<UParticleSystem> ArbitraryParticleName2(TEXT("ParticleSystem'/Game/FirstPerson/Particles/P_Water_Projectile.P_Water_Projectile'"));
	particleList.Add(ArbitraryParticleName2.Object);
	ConstructorHelpers::FObjectFinder<UParticleSystem> ArbitraryParticleName3(TEXT("ParticleSystem'/Game/FirstPerson/Particles/P_Ice_Projectile.P_Ice_Projectile'"));
	particleList.Add(ArbitraryParticleName3.Object);
	ConstructorHelpers::FObjectFinder<UParticleSystem> ArbitraryParticleName4(TEXT("ParticleSystem'/Game/FirstPerson/Particles/P_Earth_Projectile.P_Earth_Projectile'"));
	particleList.Add(ArbitraryParticleName4.Object);
	//Now for all of the EXPLOSIONS
	ConstructorHelpers::FObjectFinder<UParticleSystem> ArbitraryParticleName5(TEXT("ParticleSystem'/Game/FirstPerson/Particles/P_Fire_Blast.P_Fire_Blast'"));
	particleList.Add(ArbitraryParticleName5.Object);
	ConstructorHelpers::FObjectFinder<UParticleSystem> ArbitraryParticleName6(TEXT("ParticleSystem'/Game/FirstPerson/Particles/P_Lightning_Blast.P_Lightning_Blast'"));
	particleList.Add(ArbitraryParticleName6.Object);
	ConstructorHelpers::FObjectFinder<UParticleSystem> ArbitraryParticleName7(TEXT("ParticleSystem'/Game/FirstPerson/Particles/P_Water_Blast.P_Water_Blast'"));
	particleList.Add(ArbitraryParticleName7.Object);
	ConstructorHelpers::FObjectFinder<UParticleSystem> ArbitraryParticleName8(TEXT("ParticleSystem'/Game/FirstPerson/Particles/P_Ice_Blast.P_Ice_Blast'"));
	particleList.Add(ArbitraryParticleName8.Object);
	ConstructorHelpers::FObjectFinder<UParticleSystem> ArbitraryParticleName9(TEXT("ParticleSystem'/Game/FirstPerson/Particles/P_Earth_Blast.P_Earth_Blast'"));
	particleList.Add(ArbitraryParticleName9.Object);
	//Next up is cones
	ConstructorHelpers::FObjectFinder<UParticleSystem> ArbitraryParticleName10(TEXT("ParticleSystem'/Game/FirstPerson/Particles/P_Fire_Cone.P_Fire_Cone'"));
	particleList.Add(ArbitraryParticleName10.Object);
	ConstructorHelpers::FObjectFinder<UParticleSystem> ArbitraryParticleName11(TEXT("ParticleSystem'/Game/FirstPerson/Particles/P_Lightning_Cone.P_Lightning_Cone'"));
	particleList.Add(ArbitraryParticleName11.Object);
	ConstructorHelpers::FObjectFinder<UParticleSystem> ArbitraryParticleName12(TEXT("ParticleSystem'/Game/FirstPerson/Particles/P_Water_Cone.P_Water_Cone'"));
	particleList.Add(ArbitraryParticleName12.Object);
	ConstructorHelpers::FObjectFinder<UParticleSystem> ArbitraryParticleName13(TEXT("ParticleSystem'/Game/FirstPerson/Particles/P_Ice_Cone.P_Ice_Cone'"));
	particleList.Add(ArbitraryParticleName13.Object);
	ConstructorHelpers::FObjectFinder<UParticleSystem> ArbitraryParticleName14(TEXT("ParticleSystem'/Game/FirstPerson/Particles/P_Earth_Cone.P_Earth_Cone'"));
	particleList.Add(ArbitraryParticleName14.Object);


	//spell test;
	//SList.Add(test);
	//SList[currSpell].spellCost = 10.0;
	//SList[currSpell].theWizard = this;
	//SList[currSpell].canBounce = true;
	//ConstructorHelpers::FObjectFinder<UParticleSystem> ArbitraryParticleName8(TEXT("ParticleSystem'/Game/StarterContent/Particles/P_Sparks.P_Sparks'"));
	//SList[currSpell].myParticle = ArbitraryParticleName8.Object;
	//SList.test = &ArbitraryParticleName;
	//SList.particleLocation = FName(TEXT("ParticleSystem'/Game/StarterContent/Particles/P_Sparks.P_Sparks'"));

	// Set size for collision capsule
	GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f);

	// set our turn rates for input
	BaseTurnRate = 45.f;
	BaseLookUpRate = 45.f;

	// Create a CameraComponent	
	FirstPersonCameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("FirstPersonCamera"));
	FirstPersonCameraComponent->AttachParent = GetCapsuleComponent();
	FirstPersonCameraComponent->RelativeLocation = FVector(0, 0, 64.f); // Position the camera
	FirstPersonCameraComponent->bUsePawnControlRotation = true;

	// Default offset from the character location for projectiles to spawn
	GunOffset = FVector(100.0f, 30.0f, 10.0f);

	// Create a mesh component that will be used when being viewed from a '1st person' view (when controlling this pawn)
	Mesh1P = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("CharacterMesh1P"));
	Mesh1P->SetOnlyOwnerSee(true);			// only the owning player will see this mesh
	Mesh1P->AttachParent = FirstPersonCameraComponent;
	Mesh1P->RelativeLocation = FVector(0.f, 0.f, -150.f);
	Mesh1P->bCastDynamicShadow = false;
	Mesh1P->CastShadow = false;

	// Note: The ProjectileClass and the skeletal mesh/anim blueprints for Mesh1P are set in the
	// derived blueprint asset named MyCharacter (to avoid direct content references in C++)
}
bool ADEPRECATED_VolumeAdaptiveBuilder::GrowNAVVolumeByIndex(UDoNNavigationVolumeComponent* volume, int32 XGrowth, int32 YGrowth, int32 ZGrowth)
{	
	bool infantVolume = XGrowth == 1 && ZGrowth == 1 && YGrowth == 1;

	float xBoxExtent = (XGrowth * XBaseUnit + (XGrowth - 1)*OffsetThickness) / 2;
	float yBoxExtent = (YGrowth * YBaseUnit + (YGrowth - 1)*OffsetThickness) / 2;
	float zBoxExtent = (ZGrowth * ZBaseUnit + (ZGrowth - 1)*OffsetThickness) / 2;

	float x = xBoxExtent + (XBaseUnit + OffsetThickness) * volume->X + GetActorLocation().X;
	float y = yBoxExtent + (YBaseUnit + OffsetThickness) * volume->Y + GetActorLocation().Y;	
	float z = zBoxExtent + (ZBaseUnit + OffsetThickness) * (volume->Z + 1 - ZGrowth) + GetActorLocation().Z;
	
	FVector originalWorldLocation = volume->GetComponentLocation();
	FVector originalBoxExtent = volume->GetUnscaledBoxExtent();		
	volume->SetWorldLocation(FVector(x, y, z));
	volume->SetBoxExtent(FVector(xBoxExtent, yBoxExtent, zBoxExtent));

	TArray<UPrimitiveComponent*> obstacles;	
	UKismetSystemLibrary::ComponentOverlapComponents_NEW(volume, volume->GetComponentTransform(), ObstacleList, NULL, ActorsToIgnoreForCollision, obstacles);

	if (obstacles.Num() > 0)
	{
		if (infantVolume)
		{
			/*volume->CanNavigate = false;volume->ShapeColor = FColor::Red;*/
			NAVVolumeComponents.Remove(volume);
			volume->DestroyComponent();

			return false;
		}
		else
		{
			volume->SetWorldLocation(originalWorldLocation);
			volume->SetBoxExtent(originalBoxExtent);
		}

		return false;
	}
	else
	{
		TArray<UPrimitiveComponent*> neighboringVolumeComponents;		
		UKismetSystemLibrary::ComponentOverlapComponents_NEW(volume, volume->GetComponentTransform(), NAVOverlapQuery, UDoNNavigationVolumeComponent::StaticClass(), ActorsToIgnoreForCollision, neighboringVolumeComponents);
		neighboringVolumeComponents.Remove(volume);		

		if (neighboringVolumeComponents.Num() > 0)
		{
			if (infantVolume)
			{
				// Seed has landed on existing volume, destroy it immediately
				NAVVolumeComponents.Remove(volume);
				volume->DestroyComponent();

				return false;
			}
			else
			{
				volume->SetWorldLocation(originalWorldLocation);
				volume->SetBoxExtent(originalBoxExtent);
			}

			return false;
		}
		else
		{
			volume->UpdateBounds();
			return true;
		}
			
	}
	
}
Beispiel #21
0
void ADefaultPlayerstate::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);


	ANpcController* NpcController;

	if (NpcSortTimer <= 0) 
	{
		TaskPriorities.Empty();
		NpcSortTimer = NpcSortFrequency;
		
		for (int32 NpcSortIndex = 0; NpcSortIndex < OwnedNpcs.Num(); NpcSortIndex++)
		{
			if (OwnedNpcs[NpcSortIndex]->IsValidLowLevel())
			{
				NpcController = Cast<ANpcController>(OwnedNpcs[NpcSortIndex]->GetController());
				if (NpcController && NpcController->Job == ENpcJob::StorageWorker)
				{
					TaskPriorities.Add(NpcSortIndex + NpcController->Tasks.Num() * 1000);
				}
			}
		}
		TaskPriorities.Sort();

		for (int32 TaskPriority = 0; TaskPriority<TaskPriorities.Num(); TaskPriority++)
		{
			TaskPriorities[TaskPriority] -= FMath::Floor(TaskPriorities[TaskPriority]/1000)*1000;
			UE_LOG(LogTemp, Warning, TEXT("TaskPriority: %d"), TaskPriorities[TaskPriority]);
		}
			
	}
	else
	{
		NpcSortTimer -= DeltaTime;
	}

	//int32 End;

	int32 StartNpc = 0;
	int32 EndNpc = 0;
	int32 PawnCount = OwnedNpcs.Num();
	int32 NpcsToIterate = 0;

	if (NpcProgression >= PawnCount) {
		NpcProgression = 0;
	}

	
	if (PawnCount >= 1 && PawnCount <= 100)
	{
		if (PawnCount < 20) {
			NpcsToIterate = PawnCount;
		}
		else {
			NpcsToIterate = 20;
		}
	}
	else if (PawnCount > 100)
	{
		NpcsToIterate = FMath::Min(PawnCount / 5, 50);
	}

	
	StartNpc = FMath::Min(NpcProgression, OwnedNpcs.Num());
	EndNpc = FMath::Min(StartNpc + NpcsToIterate, OwnedNpcs.Num());
	NpcProgression += NpcsToIterate + 1;

	//UE_LOG(LogTemp, Warning, TEXT("%d Npc: %d - %d, %d"), NpcsToIterate, StartNpc, EndNpc, int(1 / DeltaTime));

	for (int32 NpcIndex = StartNpc; NpcIndex < EndNpc; NpcIndex++)
	{

		NpcController = Cast<ANpcController>(OwnedNpcs[NpcIndex]->GetController());
		if (NpcController)
		{
			if (FVector::Dist(NpcController->TargetLocation, NpcController->GetPawn()->GetActorLocation()) < 250.f || NpcController->Tasks.Num() > 0 && NpcController->Tasks[0] == ENpcTask::Free && NpcController->Tasks.Num() > 1)
			{

				NpcController->bTargetReached = true;
				NpcController->bMoving = false;

				APlayerCharacter* PlayerCharacter = Cast<APlayerCharacter>(NpcController->GetPawn()->GetOwner());
				AResourceBuilding* ResourceBuilding;
				switch (NpcController->Tasks[0])
				{
				case ENpcTask::Free:
					break;

				case ENpcTask::PickupItemsFromBuilding:


					ResourceBuilding = Cast<AResourceBuilding>(NpcController->TargetActors[0]);
					if (ResourceBuilding)
					{
						NpcController->CarriedItemID = ResourceBuilding->ProductionID;
						NpcController->CarriedItemQuantity = FMath::Min(ResourceBuilding->CurrentProductionQuantity, NpcController->MaxCarriedItemQuantity);
						ResourceBuilding->CurrentProductionQuantity -= NpcController->CarriedItemQuantity;
						ResourceBuilding->GrowProgression = 0.f;
						ResourceBuilding->GrowProgressionState = 0;
						ResourceBuilding->CalledNpc = false;


					}
					break;



				case ENpcTask::DropItemsToStorage:
					if (PlayerCharacter){ PlayerCharacter->ChangeItem(NpcController->CarriedItemID, NpcController->CarriedItemQuantity); }
					NpcController->CarriedItemID = NpcController->CarriedItemQuantity = 0;
					//Task = ENpcTask::Free;
					break;

				case ENpcTask::PickupItemsFromStorage:
					NpcController->CarriedItemID = NpcController->NeededItemID;
					NpcController->CarriedItemQuantity = FMath::Min(FMath::Min(NpcController->NeededItemQuantity, PlayerCharacter->CheckForQuantity(NpcController->NeededItemID)), NpcController->MaxCarriedItemQuantity);
					NpcController->NeededItemID = NpcController->NeededItemQuantity = 0;
					if (PlayerCharacter){ PlayerCharacter->ChangeItem(NpcController->CarriedItemID, -NpcController->CarriedItemQuantity); }
					break;


				case ENpcTask::DropItemsToBuilding:
					ResourceBuilding = Cast<AResourceBuilding>(NpcController->TargetActors[0]);
					if (ResourceBuilding)
					{

						int32 OldConsumption;
						OldConsumption = ResourceBuilding->CurrentConsumptionQuantity;
						//ResourceBuilding->CurrentConsumptionQuantity = FMath::Min(ResourceBuilding->ConsumptionQuantity, ResourceBuilding->CurrentConsumptionQuantity + CarriedItemQuantity);


						if (Role == ROLE_Authority)
						{
							ResourceBuilding->SendConsumeStateUpdateToClients(float(FMath::Min(ResourceBuilding->ConsumptionQuantity, ResourceBuilding->CurrentConsumptionQuantity + NpcController->CarriedItemQuantity) - 1) / ResourceBuilding->ConsumptionQuantity);
							ResourceBuilding->CalledNpc = false;
						}
						ResourceBuilding->GrowProgressionState = 0;
						
						NpcController->CarriedItemQuantity -= ResourceBuilding->CurrentConsumptionQuantity - OldConsumption;
						if (NpcController->CarriedItemQuantity <= 0)
						{
							NpcController->CarriedItemID = NpcController->CarriedItemQuantity = 0;
						}
						else
						{
							NpcController->AddTask(ENpcTask::DropItemsToStorage, PlayerCharacter->OwnedStorageBuilding, ENpcTaskPriority::Urgent);
							UE_LOG(LogTemp, Warning, TEXT("fuck dis shiat"));
						}
					}
					break;



				}

				NpcController->Tasks.RemoveAt(0);
				if (NpcController->Tasks.Num() == 0)
				{
					NpcController->Tasks.Add(ENpcTask::Free);
				}
				else
				{


					if (NpcController->TargetActors.Num() == 0)
					{
						NpcController->bTargetReached = true;
						return;
					}
					else
					{
						NpcController->TargetActors.RemoveAt(0);
					}


					NpcController->bTargetReached = false;
					switch (NpcController->Tasks[0])
					{
					case ENpcTask::Free:
						NpcController->bTargetReached = true;
						return;

					case ENpcTask::DropItemsToBuilding:
						NpcController->TargetLocation = NpcController->TargetActors[0]->GetActorLocation();
						break;

					case ENpcTask::DropItemsToStorage:
						NpcController->TargetLocation = FVector(0, 0, 0);
						if (NpcController->TargetActors[0] != NULL)
						{
							NpcController->TargetLocation = NpcController->TargetActors[0]->GetActorLocation();
						}
						break;

					case ENpcTask::PickupItemsFromBuilding:
						NpcController->TargetLocation = NpcController->TargetActors[0]->GetActorLocation();
						break;

					case ENpcTask::PickupItemsFromStorage:
						NpcController->TargetLocation = FVector(0, 0, 0);
						if (NpcController->TargetActors[0] != NULL)
						{
							NpcController->TargetLocation = NpcController->TargetActors[0]->GetActorLocation();
						}
						break;


					case ENpcTask::GetBuildingConsumption:
						ResourceBuilding = Cast<AResourceBuilding>(NpcController->TargetActors[0]);
						if (ResourceBuilding)
						{

							NpcController->NeededItemID = ResourceBuilding->ConsumptionID;
							NpcController->NeededItemQuantity = ResourceBuilding->ConsumptionQuantity - ResourceBuilding->CurrentConsumptionQuantity;


							//TargetActor = PlayerCharacter->OwnedStorageBuilding;
							NpcController->TargetLocation = NpcController->GetPawn()->GetActorLocation();
						}

						break;



					}

				}


			}
			else if (!NpcController->bTargetReached && !NpcController->bMoving)
			{
				APawn* const Pawn = NpcController->GetPawn();
				if (Pawn)
				{

					UNavigationSystem* const NavSys = GetWorld()->GetNavigationSystem();
					float const Distance = FVector::Dist(NpcController->TargetLocation, Pawn->GetActorLocation());

					if (NavSys && Distance > 150.f)
					{
						NpcController->MoveToLocation(NpcController->TargetLocation, 150.f);
						NpcController->bMoving = true;
					}
				}
			}
		}
	}
}
void ADEPRECATED_VolumeAdaptiveBuilder::BuildNAVNetwork()
{	
	NavGraph.nodes = TMap<UDoNNavigationVolumeComponent*, TArray<UDoNNavigationVolumeComponent*>>();
	
	for (auto Iter(NAVVolumeComponents.CreateIterator()); Iter; Iter++)
	{
		if (!Iter)
			continue;

		UDoNNavigationVolumeComponent* volume = (*Iter);		
		TArray<UPrimitiveComponent*> neighboringVolumeComponents;	

		volume->UpdateBounds(); // GetBoxExtrema functions return outdated values unless this is called after a volume has grown to desired size
		volume->CanNavigate = true;
		volume->ShapeColor = FColor::Green;		

		FVector originalBoxExtent = volume->GetUnscaledBoxExtent();		
		volume->SetBoxExtent(FVector(originalBoxExtent.X + XBaseUnit / 2, originalBoxExtent.Y + YBaseUnit / 2, originalBoxExtent.Z + ZBaseUnit/2));		
		UKismetSystemLibrary::ComponentOverlapComponents_NEW(volume, volume->GetComponentTransform(), NAVOverlapQuery, UDoNNavigationVolumeComponent::StaticClass(), ActorsToIgnoreForCollision, neighboringVolumeComponents);
		volume->SetBoxExtent(originalBoxExtent);		

		neighboringVolumeComponents.Remove(volume);
		volume->UpdateBounds();

		TArray<UDoNNavigationVolumeComponent*> neighbors;
		for (UPrimitiveComponent* neighbor : neighboringVolumeComponents)
		{
			neighbor->UpdateBounds();
			
			bool overlapsX = VolumesOverlapAxis2(volume->Bounds.GetBoxExtrema(0).X, volume->Bounds.GetBoxExtrema(1).X, neighbor->Bounds.GetBoxExtrema(0).X, neighbor->Bounds.GetBoxExtrema(1).X);
			bool overlapsY = VolumesOverlapAxis2(volume->Bounds.GetBoxExtrema(0).Y, volume->Bounds.GetBoxExtrema(1).Y, neighbor->Bounds.GetBoxExtrema(0).Y, neighbor->Bounds.GetBoxExtrema(1).Y);
			bool overlapsZ = VolumesOverlapAxis2(volume->Bounds.GetBoxExtrema(0).Z, volume->Bounds.GetBoxExtrema(1).Z, neighbor->Bounds.GetBoxExtrema(0).Z, neighbor->Bounds.GetBoxExtrema(1).Z);
			bool pathExists = (overlapsX && overlapsY) || (overlapsY && overlapsZ) || (overlapsZ && overlapsX);
			if (!pathExists)
				continue;				

			neighbors.Add(Cast<UDoNNavigationVolumeComponent>(neighbor));

			if (DisplayNAVNeighborGraph)
			{
				DrawDebugPoint(GetWorld(), volume->GetComponentLocation(), 10.f, FColor::Blue, true);
				DrawDebugLine(GetWorld(), volume->GetComponentLocation(), neighbor->GetComponentLocation(), FColor::Red, true, -1.f, 0, 4.f);
				
				/*if (volume->X == 88 && volume->Y == 169 && volume->Z == 7)
				{					
					volume->ShapeColor = FColor::Red;
					Cast<UDoNNavigationVolumeComponent>(neighbor)->ShapeColor = FColor::Blue;
				}*/

				volume->SetVisibility(true);
				neighbor->SetVisibility(true);
				
			}
		}			

		NavGraph.nodes.Add((*Iter), neighbors);

		// [Old code] Special workaround for persisting UObject volumes onto a UMAP. Not applicable for pixel builders ATM
		FNAVMapContainer NAVMapContainer;
		NAVMapContainer.volume = volume;
		NAVMapContainer.neighbors = neighbors;
		NavGraph_GCSafe.Add(NAVMapContainer);		
	}
}
FVector UPhysicsSpringComponent::GetSpringDirection() const
{
	return ComponentToWorld.TransformVectorNoScale(FVector(1.f, 0.f, 0.f));
}
void URuntimeMeshLibrary::CalculateTangentsForMesh(TFunction<int32(int32 Index)> IndexAccessor, TFunction<FVector(int32 Index)> VertexAccessor, TFunction<FVector2D(int32 Index)> UVAccessor,
	TFunction<void(int32 Index, FVector TangentX, FVector TangentY, FVector TangentZ)> TangentSetter, int32 NumVertices, int32 NumUVs, int32 NumIndices, bool bCreateSmoothNormals)
{
	SCOPE_CYCLE_COUNTER(STAT_RuntimeMeshLibrary_CalculateTangentsForMesh);

	if (NumVertices == 0 || NumIndices == 0)
	{
		return;
	}

	// Calculate the duplicate vertices map if we're wanting smooth normals.  Don't find duplicates if we don't want smooth normals
	// that will cause it to only smooth across faces sharing a common vertex, not across faces with vertices of common position
	const TMultiMap<uint32, uint32> DuplicateVertexMap = bCreateSmoothNormals ? FRuntimeMeshInternalUtilities::FindDuplicateVerticesMap(VertexAccessor, NumVertices) : TMultiMap<uint32, uint32>();


	// Number of triangles
	const int32 NumTris = NumIndices / 3;

	// Map of vertex to triangles in Triangles array
	TMultiMap<uint32, uint32> VertToTriMap;
	// Map of vertex to triangles to consider for normal calculation
	TMultiMap<uint32, uint32> VertToTriSmoothMap;

	// Normal/tangents for each face
	TArray<FVector> FaceTangentX, FaceTangentY, FaceTangentZ;
	FaceTangentX.AddUninitialized(NumTris);
	FaceTangentY.AddUninitialized(NumTris);
	FaceTangentZ.AddUninitialized(NumTris);

	// Iterate over triangles
	for (int TriIdx = 0; TriIdx < NumTris; TriIdx++)
	{
		uint32 CornerIndex[3];
		FVector P[3];

		for (int32 CornerIdx = 0; CornerIdx < 3; CornerIdx++)
		{
			// Find vert index (clamped within range)
			uint32 VertIndex = FMath::Min(IndexAccessor((TriIdx * 3) + CornerIdx), NumVertices - 1);

			CornerIndex[CornerIdx] = VertIndex;
			P[CornerIdx] = VertexAccessor(VertIndex);

			// Find/add this vert to index buffer
			TArray<uint32> VertOverlaps;
			DuplicateVertexMap.MultiFind(VertIndex, VertOverlaps);

			// Remember which triangles map to this vert
			VertToTriMap.AddUnique(VertIndex, TriIdx);
			VertToTriSmoothMap.AddUnique(VertIndex, TriIdx);

			// Also update map of triangles that 'overlap' this vert (ie don't match UV, but do match smoothing) and should be considered when calculating normal
			for (int32 OverlapIdx = 0; OverlapIdx < VertOverlaps.Num(); OverlapIdx++)
			{
				// For each vert we overlap..
				int32 OverlapVertIdx = VertOverlaps[OverlapIdx];

				// Add this triangle to that vert
				VertToTriSmoothMap.AddUnique(OverlapVertIdx, TriIdx);

				// And add all of its triangles to us
				TArray<uint32> OverlapTris;
				VertToTriMap.MultiFind(OverlapVertIdx, OverlapTris);
				for (int32 OverlapTriIdx = 0; OverlapTriIdx < OverlapTris.Num(); OverlapTriIdx++)
				{
					VertToTriSmoothMap.AddUnique(VertIndex, OverlapTris[OverlapTriIdx]);
				}
			}
		}

		// Calculate triangle edge vectors and normal
		const FVector Edge21 = P[1] - P[2];
		const FVector Edge20 = P[0] - P[2];
		const FVector TriNormal = (Edge21 ^ Edge20).GetSafeNormal();

		// If we have UVs, use those to calculate
		if (NumUVs == NumVertices)
		{
			const FVector2D T1 = UVAccessor(CornerIndex[0]);
			const FVector2D T2 = UVAccessor(CornerIndex[1]);
			const FVector2D T3 = UVAccessor(CornerIndex[2]);

// 			float X1 = P[1].X - P[0].X;
// 			float X2 = P[2].X - P[0].X;
// 			float Y1 = P[1].Y - P[0].Y;
// 			float Y2 = P[2].Y - P[0].Y;
// 			float Z1 = P[1].Z - P[0].Z;
// 			float Z2 = P[2].Z - P[0].Z;
// 
// 			float S1 = U1.X - U0.X;
// 			float S2 = U2.X - U0.X;
// 			float T1 = U1.Y - U0.Y;
// 			float T2 = U2.Y - U0.Y;
// 
// 			float R = 1.0f / (S1 * T2 - S2 * T1);
// 			FaceTangentX[TriIdx] = FVector((T2 * X1 - T1 * X2) * R, (T2 * Y1 - T1 * Y2) * R,
// 				(T2 * Z1 - T1 * Z2) * R);
// 			FaceTangentY[TriIdx] = FVector((S1 * X2 - S2 * X1) * R, (S1 * Y2 - S2 * Y1) * R,
// 				(S1 * Z2 - S2 * Z1) * R);




			FMatrix	ParameterToLocal(
				FPlane(P[1].X - P[0].X, P[1].Y - P[0].Y, P[1].Z - P[0].Z, 0),
				FPlane(P[2].X - P[0].X, P[2].Y - P[0].Y, P[2].Z - P[0].Z, 0),
				FPlane(P[0].X, P[0].Y, P[0].Z, 0),
				FPlane(0, 0, 0, 1)
			);

			FMatrix ParameterToTexture(
				FPlane(T2.X - T1.X, T2.Y - T1.Y, 0, 0),
				FPlane(T3.X - T1.X, T3.Y - T1.Y, 0, 0),
				FPlane(T1.X, T1.Y, 1, 0),
				FPlane(0, 0, 0, 1)
			);

			// Use InverseSlow to catch singular matrices.  Inverse can miss this sometimes.
			const FMatrix TextureToLocal = ParameterToTexture.Inverse() * ParameterToLocal;

			FaceTangentX[TriIdx] = TextureToLocal.TransformVector(FVector(1, 0, 0)).GetSafeNormal();
			FaceTangentY[TriIdx] = TextureToLocal.TransformVector(FVector(0, 1, 0)).GetSafeNormal();
		}
		else
		{
			FaceTangentX[TriIdx] = Edge20.GetSafeNormal();
			FaceTangentY[TriIdx] = (FaceTangentX[TriIdx] ^ TriNormal).GetSafeNormal();
		}

		FaceTangentZ[TriIdx] = TriNormal;
	}


	// Arrays to accumulate tangents into
	TArray<FVector> VertexTangentXSum, VertexTangentYSum, VertexTangentZSum;
	VertexTangentXSum.AddZeroed(NumVertices);
	VertexTangentYSum.AddZeroed(NumVertices);
	VertexTangentZSum.AddZeroed(NumVertices);

	// For each vertex..
	for (int VertxIdx = 0; VertxIdx < NumVertices; VertxIdx++)
	{
		// Find relevant triangles for normal
		TArray<uint32> SmoothTris;
		VertToTriSmoothMap.MultiFind(VertxIdx, SmoothTris);

		for (int i = 0; i < SmoothTris.Num(); i++)
		{
			uint32 TriIdx = SmoothTris[i];
			VertexTangentZSum[VertxIdx] += FaceTangentZ[TriIdx];
		}

		// Find relevant triangles for tangents
		TArray<uint32> TangentTris;
		VertToTriMap.MultiFind(VertxIdx, TangentTris);

		for (int i = 0; i < TangentTris.Num(); i++)
		{
			uint32 TriIdx = TangentTris[i];
			VertexTangentXSum[VertxIdx] += FaceTangentX[TriIdx];
			VertexTangentYSum[VertxIdx] += FaceTangentY[TriIdx];
		}
	}

	// Finally, normalize tangents and build output arrays	
	for (int VertxIdx = 0; VertxIdx < NumVertices; VertxIdx++)
	{
		FVector& TangentX = VertexTangentXSum[VertxIdx];
		FVector& TangentY = VertexTangentYSum[VertxIdx];
		FVector& TangentZ = VertexTangentZSum[VertxIdx];

		TangentX.Normalize();
		//TangentY.Normalize();
		TangentZ.Normalize();

		// Use Gram-Schmidt orthogonalization to make sure X is orthonormal with Z
		TangentX -= TangentZ * (TangentZ | TangentX);
		TangentX.Normalize();
		TangentY.Normalize();


		TangentSetter(VertxIdx, TangentX, TangentY, TangentZ);
	}
}
FVector UKismetMathLibrary::Conv_LinearColorToVector(FLinearColor InLinearColor)
{
	return FVector(InLinearColor);
}
void FAnimNode_Trail::EvaluateBoneTransforms(USkeletalMeshComponent* SkelComp, FCSPose<FCompactPose>& MeshBases, TArray<FBoneTransform>& OutBoneTransforms)
{
	check(OutBoneTransforms.Num() == 0);

	if( ChainLength < 2 )
	{
		return;
	}

	// The incoming BoneIndex is the 'end' of the spline chain. We need to find the 'start' by walking SplineLength bones up hierarchy.
	// Fail if we walk past the root bone.

	const FBoneContainer& BoneContainer = MeshBases.GetPose().GetBoneContainer();
	FCompactPoseBoneIndex WalkBoneIndex = TrailBone.GetCompactPoseIndex(BoneContainer);

	TArray<FCompactPoseBoneIndex> ChainBoneIndices;
	ChainBoneIndices.AddZeroed(ChainLength);

	ChainBoneIndices[ChainLength - 1] = WalkBoneIndex;

	for (int32 i = 1; i < ChainLength; i++)
	{
		// returns to avoid a crash
		// @TODO : shows an error message why failed
		if (WalkBoneIndex == 0)
		{
			return;
		}

		// Get parent bone.
		WalkBoneIndex = BoneContainer.GetParentBoneIndex(WalkBoneIndex);

		//Insert indices at the start of array, so that parents are before children in the array.
		int32 TransformIndex = ChainLength - (i + 1);
		ChainBoneIndices[TransformIndex] = WalkBoneIndex;
	}

	OutBoneTransforms.AddZeroed(ChainLength);

	// If we have >0 this frame, but didn't last time, record positions of all the bones.
	// Also do this if number has changed or array is zero.
	bool bHasValidStrength = (Alpha > 0.f);
	if(TrailBoneLocations.Num() != ChainLength || (bHasValidStrength && !bHadValidStrength))
	{
		TrailBoneLocations.Empty();
		TrailBoneLocations.AddZeroed(ChainLength);

		for(int32 i=0; i<ChainBoneIndices.Num(); i++)
		{
			FCompactPoseBoneIndex ChildIndex = ChainBoneIndices[i];
			const FTransform& ChainTransform = MeshBases.GetComponentSpaceTransform(ChildIndex);
			TrailBoneLocations[i] = ChainTransform.GetTranslation();
		}
		OldLocalToWorld = SkelComp->GetTransformMatrix();
	}
	bHadValidStrength = bHasValidStrength;

	// transform between last frame and now.
	FMatrix OldToNewTM = OldLocalToWorld * SkelComp->GetTransformMatrix().InverseFast();

	// Add fake velocity if present to all but root bone
	if(!FakeVelocity.IsZero())
	{
		FVector FakeMovement = -FakeVelocity * ThisTimstep;

		if (bActorSpaceFakeVel && SkelComp->GetOwner())
		{
			const FTransform BoneToWorld(SkelComp->GetOwner()->GetActorQuat(), SkelComp->GetOwner()->GetActorLocation());
			FakeMovement = BoneToWorld.TransformVector(FakeMovement);
		}

		FakeMovement = SkelComp->GetTransformMatrix().InverseTransformVector(FakeMovement);
		// Then add to each bone
		for(int32 i=1; i<TrailBoneLocations.Num(); i++)
		{
			TrailBoneLocations[i] += FakeMovement;
		}
	}

	// Root bone of trail is not modified.
	FCompactPoseBoneIndex RootIndex = ChainBoneIndices[0]; 
	const FTransform& ChainTransform = MeshBases.GetComponentSpaceTransform(RootIndex);
	OutBoneTransforms[0] = FBoneTransform(RootIndex, ChainTransform);
	TrailBoneLocations[0] = ChainTransform.GetTranslation();

	// Starting one below head of chain, move bones.
	for(int32 i=1; i<ChainBoneIndices.Num(); i++)
	{
		// Parent bone position in component space.
		FCompactPoseBoneIndex ParentIndex = ChainBoneIndices[i - 1];
		FVector ParentPos = TrailBoneLocations[i-1];
		FVector ParentAnimPos = MeshBases.GetComponentSpaceTransform(ParentIndex).GetTranslation();

		// Child bone position in component space.
		FCompactPoseBoneIndex ChildIndex = ChainBoneIndices[i];
		FVector ChildPos = OldToNewTM.TransformPosition(TrailBoneLocations[i]); // move from 'last frames component' frame to 'this frames component' frame
		FVector ChildAnimPos = MeshBases.GetComponentSpaceTransform(ChildIndex).GetTranslation();

		// Desired parent->child offset.
		FVector TargetDelta = (ChildAnimPos - ParentAnimPos);

		// Desired child position.
		FVector ChildTarget = ParentPos + TargetDelta;

		// Find vector from child to target
		FVector Error = ChildTarget - ChildPos;

		// Calculate how much to push the child towards its target
		float Correction = FMath::Clamp<float>(ThisTimstep * TrailRelaxation, 0.f, 1.f);

		// Scale correction vector and apply to get new world-space child position.
		TrailBoneLocations[i] = ChildPos + (Error * Correction);

		// If desired, prevent bones stretching too far.
		if(bLimitStretch)
		{
			float RefPoseLength = TargetDelta.Size();
			FVector CurrentDelta = TrailBoneLocations[i] - TrailBoneLocations[i-1];
			float CurrentLength = CurrentDelta.Size();

			// If we are too far - cut it back (just project towards parent particle).
			if( (CurrentLength - RefPoseLength > StretchLimit) && CurrentLength > SMALL_NUMBER )
			{
				FVector CurrentDir = CurrentDelta / CurrentLength;
				TrailBoneLocations[i] = TrailBoneLocations[i-1] + (CurrentDir * (RefPoseLength + StretchLimit));
			}
		}

		// Modify child matrix
		OutBoneTransforms[i] = FBoneTransform(ChildIndex, MeshBases.GetComponentSpaceTransform(ChildIndex));
		OutBoneTransforms[i].Transform.SetTranslation(TrailBoneLocations[i]);

		// Modify rotation of parent matrix to point at this one.

		// Calculate the direction that parent bone is currently pointing.
		FVector CurrentBoneDir = OutBoneTransforms[i-1].Transform.TransformVector( GetAlignVector(ChainBoneAxis, bInvertChainBoneAxis) );
		CurrentBoneDir = CurrentBoneDir.GetSafeNormal(SMALL_NUMBER);

		// Calculate vector from parent to child.
		FVector NewBoneDir = FVector(OutBoneTransforms[i].Transform.GetTranslation() - OutBoneTransforms[i - 1].Transform.GetTranslation()).GetSafeNormal(SMALL_NUMBER);

		// Calculate a quaternion that gets us from our current rotation to the desired one.
		FQuat DeltaLookQuat = FQuat::FindBetween(CurrentBoneDir, NewBoneDir);
		FTransform DeltaTM( DeltaLookQuat, FVector(0.f) );

		// Apply to the current parent bone transform.
		FTransform TmpMatrix = FTransform::Identity;
		TmpMatrix.CopyRotationPart(OutBoneTransforms[i - 1].Transform);
		TmpMatrix = TmpMatrix * DeltaTM;
		OutBoneTransforms[i - 1].Transform.CopyRotationPart(TmpMatrix);
	}

	// For the last bone in the chain, use the rotation from the bone above it.
	OutBoneTransforms[ChainLength - 1].Transform.CopyRotationPart(OutBoneTransforms[ChainLength - 2].Transform);

	// Update OldLocalToWorld
	OldLocalToWorld = SkelComp->GetTransformMatrix();
}
FVector UKismetMathLibrary::MakeVector(float X, float Y, float Z)
{
	return FVector(X,Y,Z);
}
Beispiel #28
0
FVector ULeapImage::Rectify(FVector uv) const
{
	Leap::Vector vect = Leap::Vector(uv.X, uv.Y, uv.Z);
	vect = _private->leapImage.rectify(vect);
	return FVector(vect.x, vect.y, vect.z);
}
void UParticleModuleOrbit::Serialize(FArchive& Ar)
{
	Super::Serialize(Ar);
	if (Ar.IsLoading() && Ar.UE4Ver() < VER_UE4_MOVE_DISTRIBUITONS_TO_POSTINITPROPS)
	{
		FDistributionHelpers::RestoreDefaultUniform(OffsetAmount.Distribution, TEXT("DistributionOffsetAmount"), FVector(0.0f, 0.0f, 0.0f), FVector(0.0f, 50.0f, 0.0f));
		FDistributionHelpers::RestoreDefaultUniform(RotationAmount.Distribution, TEXT("DistributionRotationAmount"), FVector(0.0f, 0.0f, 0.0f), FVector(1.0f, 1.0f, 1.0f));
		FDistributionHelpers::RestoreDefaultUniform(RotationRateAmount.Distribution, TEXT("DistributionRotationRateAmount"), FVector(0.0f, 0.0f, 0.0f), FVector(1.0f, 1.0f, 1.0f));
	}
}
#include "LocalVertexFactory.h"
#include "MeshBatch.h"
#include "EngineGlobals.h"
#include "SceneManagement.h"
#include "Engine/Engine.h"
#include "SpriteDrawCall.h"

DECLARE_CYCLE_STAT(TEXT("Get Batch Mesh"), STAT_PaperRender_GetBatchMesh, STATGROUP_Paper2D);
DECLARE_CYCLE_STAT(TEXT("Get New Batch Meshes"), STAT_PaperRender_GetNewBatchMeshes, STATGROUP_Paper2D);
DECLARE_CYCLE_STAT(TEXT("Convert Batches"), STAT_PaperRender_ConvertBatches, STATGROUP_Paper2D);
DECLARE_CYCLE_STAT(TEXT("SpriteProxy GDME"), STAT_PaperRenderSceneProxy_GetDynamicMeshElements, STATGROUP_Paper2D);

//////////////////////////////////////////////////////////////////////////
// FPaperSpriteVertex

FPackedNormal FPaperSpriteVertex::PackedNormalX(FVector(1.0f, 0.0f, 0.0f));
FPackedNormal FPaperSpriteVertex::PackedNormalZ(FVector(0.0f, -1.0f, 0.0f));

void FPaperSpriteVertex::SetTangentsFromPaperAxes()
{
	PackedNormalX = PaperAxisX;
	PackedNormalZ = PaperAxisZ;
	// store determinant of basis in w component of normal vector
	PackedNormalZ.Vector.W = (GetBasisDeterminantSign(PaperAxisX, PaperAxisY, PaperAxisZ) < 0.0f) ? 0 : 255;
}


//////////////////////////////////////////////////////////////////////////
// FPaperSpriteVertexBuffer

class FDummyResourceArrayWrapper : public FResourceArrayInterface