FBoxSphereBounds UPaperFlipbookComponent::CalcBounds(const FTransform& LocalToWorld) const
{
	if (SourceFlipbook != nullptr)
	{
		// Graphics bounds.
		FBoxSphereBounds NewBounds = SourceFlipbook->GetRenderBounds().TransformBy(LocalToWorld);

		// Add bounds of collision geometry (if present).
		if (CachedBodySetup != nullptr)
		{
			const FBox AggGeomBox = CachedBodySetup->AggGeom.CalcAABB(LocalToWorld);
			if (AggGeomBox.IsValid)
			{
				NewBounds = Union(NewBounds, FBoxSphereBounds(AggGeomBox));
			}
		}

		// Apply bounds scale
		NewBounds.BoxExtent *= BoundsScale;
		NewBounds.SphereRadius *= BoundsScale;

		return NewBounds;
	}
	else
	{
		return FBoxSphereBounds(LocalToWorld.GetLocation(), FVector::ZeroVector, 0.f);
	}
}
void UGeometryCacheComponent::UpdateLocalBounds()
{
	FBox LocalBox(0);

	for (const FTrackRenderData& Section : TrackSections)
	{
		// Use World matrix per section for correct bounding box
		LocalBox += (Section.MeshData->BoundingBox.TransformBy(Section.WorldMatrix));
	}

	LocalBounds = LocalBox.IsValid ? FBoxSphereBounds(LocalBox) : FBoxSphereBounds(FVector(0, 0, 0), FVector(0, 0, 0), 0); // fallback to reset box sphere bounds

	UpdateBounds();
}
FBoxSphereBounds UParametricSurfaceComponent::CalcBounds(const FTransform& LocalToWorld) const
{
	const auto Radius = 100.0f;
	const auto PosMax = FVector(Radius, Radius, Radius);
	const auto PosMin = -PosMax;
	const auto Center = (PosMin + PosMax) * 0.5f;
	const auto Extent = PosMax - PosMin;
#if 0
	const auto BSB = FBoxSphereBounds(Center, Extent, Extent.Size()).TransformBy(LocalToWorld);
	const auto Box = BSB.GetBox();
	DrawDebugBox(GetWorld(), Box.GetCenter(), Box.GetExtent(), FColor::Green, true);
	return BSB;
#else
	return FBoxSphereBounds(Center, Extent, Extent.Size()).TransformBy(LocalToWorld);
#endif
}
FBoxSphereBounds UPaperGroupedSpriteComponent::CalcBounds(const FTransform& BoundTransform) const
{
	bool bHadAnyBounds = false;
	FBoxSphereBounds NewBounds(ForceInit);

	if (PerInstanceSpriteData.Num() > 0)
	{
		const FMatrix BoundTransformMatrix = BoundTransform.ToMatrixWithScale();

		for (const FSpriteInstanceData& InstanceData : PerInstanceSpriteData)
		{
			if (InstanceData.SourceSprite != nullptr)
			{
				const FBoxSphereBounds RenderBounds = InstanceData.SourceSprite->GetRenderBounds();
				const FBoxSphereBounds InstanceBounds = RenderBounds.TransformBy(InstanceData.Transform * BoundTransformMatrix);

				if (bHadAnyBounds)
				{
					NewBounds = NewBounds + InstanceBounds;
				}
				else
				{
					NewBounds = InstanceBounds;
					bHadAnyBounds = true;
				}
			}
		}
	}

	return bHadAnyBounds ? NewBounds : FBoxSphereBounds(BoundTransform.GetLocation(), FVector::ZeroVector, 0.f);
}
FBoxSphereBounds UNavMeshRenderingComponent::CalcBounds(const FTransform& LocalToWorld) const
{
	FBox BoundingBox(0);
#if WITH_RECAST
	ARecastNavMesh* NavMesh = Cast<ARecastNavMesh>(GetOwner());
	if (NavMesh)
	{
		BoundingBox = NavMesh->GetNavMeshBounds();
		if (NavMesh->bDrawOctree)
		{
			const UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(GetWorld());
			const FNavigationOctree* NavOctree = NavSys ? NavSys->GetNavOctree() : NULL;
			if (NavOctree)
			{
				for (FNavigationOctree::TConstIterator<> NodeIt(*NavOctree); NodeIt.HasPendingNodes(); NodeIt.Advance())
				{
					const FOctreeNodeContext& CorrentContext = NodeIt.GetCurrentContext();
					BoundingBox += CorrentContext.Bounds.GetBox();
				}
			}
		}
	}
#endif
	return FBoxSphereBounds(BoundingBox);
}
Esempio n. 6
0
FBoxSphereBounds UPaperTerrainComponent::CalcBounds(const FTransform& LocalToWorld) const
{
	// Determine the rendering bounds
	FBoxSphereBounds LocalRenderBounds;
	{
		FBox BoundingBox(ForceInit);

		for (const FPaperTerrainSpriteGeometry& DrawCall : GeneratedSpriteGeometry)
		{
			for (const FSpriteDrawCallRecord& Record : DrawCall.Records)
			{
				for (const FVector4& VertXYUV : Record.RenderVerts)
				{
					const FVector Vert((PaperAxisX * VertXYUV.X) + (PaperAxisY * VertXYUV.Y));
					BoundingBox += Vert;
				}
			}
		}

		// Make the whole thing a single unit 'deep'
		const FVector HalfThicknessVector = 0.5f * PaperAxisZ;
		BoundingBox.Min -= HalfThicknessVector;
		BoundingBox.Max += HalfThicknessVector;

		LocalRenderBounds = FBoxSphereBounds(BoundingBox);
	}

	// Graphics bounds.
	FBoxSphereBounds NewBounds = LocalRenderBounds.TransformBy(LocalToWorld);

	// Add bounds of collision geometry (if present).
	if (CachedBodySetup != nullptr)
	{
		const FBox AggGeomBox = CachedBodySetup->AggGeom.CalcAABB(LocalToWorld);
		if (AggGeomBox.IsValid)
		{
			NewBounds = Union(NewBounds, FBoxSphereBounds(AggGeomBox));
		}
	}

	// Apply bounds scale
	NewBounds.BoxExtent *= BoundsScale;
	NewBounds.SphereRadius *= BoundsScale;

	return NewBounds;
}
Esempio n. 7
0
FBoxSphereBounds UVoxelComponent::CalcBounds(const FTransform& LocalToWorld) const
{
	FBoxSphereBounds Bounds = FBoxSphereBounds(ForceInit);
	for (auto* InstancedStaticMeshComponent : InstancedStaticMeshComponents) {
		Bounds = Bounds + InstancedStaticMeshComponent->CalcBounds(LocalToWorld);
	}
	return Bounds;
}
FBoxSphereBounds UNavLinkRenderingComponent::CalcBounds(const FTransform& InLocalToWorld) const
{
	AActor* LinkOwnerActor = Cast<AActor>(GetOwner());
	INavLinkHostInterface* LinkOwnerHost = Cast<INavLinkHostInterface>(GetOwner());

	if (LinkOwnerActor != NULL && LinkOwnerHost != NULL)
	{
		FBox BoundingBox(0);
		const FTransform LocalToWorld = LinkOwnerActor->ActorToWorld();
		TArray<TSubclassOf<UNavLinkDefinition> > NavLinkClasses;
		TArray<FNavigationLink> SimpleLinks;
		TArray<FNavigationSegmentLink> DummySegmentLinks;

		if (LinkOwnerHost->GetNavigationLinksClasses(NavLinkClasses))
		{
			for (int32 NavLinkClassIdx = 0; NavLinkClassIdx < NavLinkClasses.Num(); ++NavLinkClassIdx)
			{
				if (NavLinkClasses[NavLinkClassIdx] != NULL)
				{
					const TArray<FNavigationLink>& Links = UNavLinkDefinition::GetLinksDefinition(NavLinkClasses[NavLinkClassIdx]);
					for (const auto& Link : Links)
					{
						BoundingBox += Link.Left;
						BoundingBox += Link.Right;
					}
				}
			}
		}
		if (LinkOwnerHost->GetNavigationLinksArray(SimpleLinks, DummySegmentLinks))
		{
			for (const auto& Link : SimpleLinks)
			{
				BoundingBox += Link.Left;
				BoundingBox += Link.Right;
			}
		}

		return FBoxSphereBounds(BoundingBox).TransformBy(LocalToWorld);
	}

	return FBoxSphereBounds(EForceInit::ForceInitToZero);
}
FBoxSphereBounds UPaperTileMapRenderComponent::CalcBounds(const FTransform& LocalToWorld) const
{
	//@TODO: Tile pivot issue
	//@TODO: Layer thickness issue
	const float HalfThickness = 2.0f;	
	const FVector TopLeft((-0.5f)*TileWidth, -HalfThickness, -(MapHeight - 0.5f) * TileHeight);
	const FVector Dimenisons(MapWidth*TileWidth, 2*HalfThickness, MapHeight * TileHeight);

	const FBox Box(TopLeft, TopLeft + Dimenisons);
	return FBoxSphereBounds(Box.TransformBy(LocalToWorld));
}
FBoxSphereBounds UNavMeshRenderingComponent::CalcBounds(const FTransform & LocalToWorld) const
{
	FBox BoundingBox(0);
#if WITH_RECAST
	ARecastNavMesh* NavMesh = Cast<ARecastNavMesh>(GetOwner());
	if (NavMesh)
	{
		BoundingBox = NavMesh->GetNavMeshBounds();
	}
#endif
	return FBoxSphereBounds(BoundingBox);
}
Esempio n. 11
0
FBoxSphereBounds UPaperTileMap::GetRenderBounds() const
{
	const float Depth = SeparationPerLayer * (TileLayers.Num() - 1);
	const float HalfThickness = 2.0f;

	const float UnrealUnitsPerPixel = GetUnrealUnitsPerPixel();
	const float TileWidthInUU = TileWidth * UnrealUnitsPerPixel;
	const float TileHeightInUU = TileHeight * UnrealUnitsPerPixel;

	switch (ProjectionMode)
	{
		case ETileMapProjectionMode::Orthogonal:
		default:
		{
			const FVector BottomLeft((-0.5f) * TileWidthInUU, -HalfThickness - Depth, -(MapHeight - 0.5f) * TileHeightInUU);
			const FVector Dimensions(MapWidth * TileWidthInUU, Depth + 2 * HalfThickness, MapHeight * TileHeightInUU);

			const FBox Box(BottomLeft, BottomLeft + Dimensions);
			return FBoxSphereBounds(Box);
		}
		case ETileMapProjectionMode::IsometricDiamond:
		{
			 const FVector BottomLeft((-0.5f) * TileWidthInUU * MapWidth, -HalfThickness - Depth, -MapHeight * TileHeightInUU);
			 const FVector Dimensions(MapWidth * TileWidthInUU, Depth + 2 * HalfThickness, (MapHeight + 1) * TileHeightInUU);

			 const FBox Box(BottomLeft, BottomLeft + Dimensions);
			 return FBoxSphereBounds(Box);
		}
		case ETileMapProjectionMode::HexagonalStaggered:
		case ETileMapProjectionMode::IsometricStaggered:
		{
			const int32 RoundedHalfHeight = (MapHeight + 1) / 2;
			const FVector BottomLeft((-0.5f) * TileWidthInUU, -HalfThickness - Depth, -(RoundedHalfHeight) * TileHeightInUU);
			const FVector Dimensions((MapWidth + 0.5f) * TileWidthInUU, Depth + 2 * HalfThickness, (RoundedHalfHeight + 1.0f) * TileHeightInUU);

			const FBox Box(BottomLeft, BottomLeft + Dimensions);
			return FBoxSphereBounds(Box);
		}
	}
}
FBoxSphereBounds UCubiquityMeshComponent::CalcBounds(const FTransform & LocalToWorld) const
{
	//UE_LOG(CubiquityLog, Log, TEXT("UCubiquityMeshComponent::CalcBounds"));
	/*FBoxSphereBounds NewBounds;
	NewBounds.Origin = FVector::ZeroVector;
	NewBounds.BoxExtent = FVector(HALF_WORLD_MAX, HALF_WORLD_MAX, HALF_WORLD_MAX);
	NewBounds.SphereRadius = FMath::Sqrt(3.0f * FMath::Square(HALF_WORLD_MAX));
	return NewBounds;*/
	//FVector BoxPoint = FVector(100, 100, 100);
	/*const FVector UnitV(1, 1, 1);
	const FBox VeryVeryBig(-UnitV * HALF_WORLD_MAX, UnitV * HALF_WORLD_MAX);
	return FBoxSphereBounds(VeryVeryBig);*/
	return FBoxSphereBounds(FBox(FVector(-128, -128, -128), FVector(128, 128, 128))).TransformBy(LocalToWorld); //TODO check this for each node...
}
Esempio n. 13
0
FBoxSphereBounds UDestructibleComponent::CalcBounds(const FTransform& LocalToWorld) const
{
#if WITH_APEX
	if( ApexDestructibleActor == NULL )
	{
		// Fallback if we don't have physics
		return Super::CalcBounds(LocalToWorld);
	}

	const PxBounds3& PBounds = ApexDestructibleActor->getBounds();

	return FBoxSphereBounds( FBox( P2UVector(PBounds.minimum), P2UVector(PBounds.maximum) ) );
#else	// #if WITH_APEX
	return Super::CalcBounds(LocalToWorld);
#endif	// #if WITH_APEX
}
FBoxSphereBounds UTextRenderComponent::CalcBounds(const FTransform& LocalToWorld) const
{
	if(!Text.IsEmpty() && Font)
	{
		FVector2D Size(FLT_MIN, 0);
		FVector2D LeftTop(FLT_MAX, FLT_MAX);
		float FirstLineHeight = -1;

		FTextIterator It(*Text.ToString());

		float AdjustedXScale = WorldSize * XScale * InvDefaultSize;
		float AdjustedYScale = WorldSize * YScale * InvDefaultSize;

		while (It.NextLine())
		{
			FVector2D LineSize = ComputeTextSize(It, Font, AdjustedXScale, AdjustedYScale, HorizSpacingAdjust);
			float LineLeft = ComputeHorizontalAlignmentOffset(LineSize, HorizontalAlignment);

			Size.X = FMath::Max(LineSize.X, Size.X);
			Size.Y += LineSize.Y > 0 ? LineSize.Y : Font->GetMaxCharHeight();
			LeftTop.X = FMath::Min(LeftTop.X, LineLeft);

			if (FirstLineHeight < 0)
			{
				FirstLineHeight = LineSize.Y;
			}

			int32 Ch;
			while (It.NextCharacterInLine(Ch));
		}

		LeftTop.Y = ComputeVerticalAlignmentOffset(Size.Y, VerticalAlignment, FirstLineHeight);
		FBox LocalBox(FVector(0, -LeftTop.X, -LeftTop.Y), FVector(0, -(LeftTop.X + Size.X), -(LeftTop.Y + Size.Y)));

		FBoxSphereBounds Ret(LocalBox.TransformBy(LocalToWorld));

		Ret.BoxExtent *= BoundsScale;
		Ret.SphereRadius *= BoundsScale;

		return Ret;
	}
	else
	{
		return FBoxSphereBounds(ForceInit);
	}
}
FBoxSphereBounds UDebugSkelMeshComponent::CalcBounds(const FTransform& LocalToWorld) const
{
	FBoxSphereBounds Result = Super::CalcBounds(LocalToWorld);

	if (! IsUsingInGameBounds())
	{
		// extend bounds by bones but without root bone
		FBox BoundingBox(0);
		for (int32 BoneIndex = 1; BoneIndex < SpaceBases.Num(); ++ BoneIndex)
		{
			BoundingBox += GetBoneMatrix(BoneIndex).GetOrigin();
		}
		Result = Result + FBoxSphereBounds(BoundingBox);
	}

	return Result;
}
	/**
	 * Sets up a projected shadow initializer for shadows from the entire scene.
	 * @return True if the whole-scene projected shadow should be used.
	 */
	virtual bool GetWholeSceneProjectedShadowInitializer(const FSceneViewFamily& ViewFamily, TArray<FWholeSceneProjectedShadowInitializer, TInlineAllocator<6> >& OutInitializers) const override
	{
		FWholeSceneProjectedShadowInitializer& OutInitializer = *new(OutInitializers) FWholeSceneProjectedShadowInitializer;
		OutInitializer.PreShadowTranslation = -GetLightToWorld().GetOrigin();
		OutInitializer.WorldToLight = GetWorldToLight().RemoveTranslation();
		OutInitializer.Scales = FVector(1.0f,InvTanOuterCone,InvTanOuterCone);
		OutInitializer.FaceDirection = FVector(1,0,0);
		OutInitializer.SubjectBounds = FBoxSphereBounds(
			GetLightToWorld().RemoveTranslation().TransformPosition(FVector(Radius, 0, 0)),
			FVector(Radius, Radius, Radius),
			Radius
			);
		OutInitializer.WAxis = FVector4(0,0,1,0);
		OutInitializer.MinLightW = 0.1f;
		OutInitializer.MaxDistanceToCastInLightW = Radius;
		OutInitializer.CascadeSettings.bRayTracedDistanceField = UseRayTracedDistanceFieldShadows() && DoesPlatformSupportDistanceFieldShadowing(ViewFamily.GetShaderPlatform());
		return true;
	}
Esempio n. 17
0
FBoxSphereBounds UPaperSprite::GetRenderBounds() const
{
	FBox BoundingBox(ForceInit);
	
	for (int32 VertexIndex = 0; VertexIndex < BakedRenderData.Num(); ++VertexIndex)
	{
		const FVector4& VertXYUV = BakedRenderData[VertexIndex];
		const FVector Vert((PaperAxisX * VertXYUV.X) + (PaperAxisY * VertXYUV.Y));
		BoundingBox += Vert;
	}
	
	// Make the whole thing a single unit 'deep'
	const FVector HalfThicknessVector = 0.5f * PaperAxisZ;
	BoundingBox.Min -= HalfThicknessVector;
	BoundingBox.Max += HalfThicknessVector;

	return FBoxSphereBounds(BoundingBox);
}
Esempio n. 18
0
void UVoxelComponent::InitVoxel()
{
	CellBounds = FBoxSphereBounds(FVector::ZeroVector, FVector(100.f, 100.f, 100.f), 100.f);
	Mesh.Empty();
	Cell.Empty();
	InstancedStaticMeshComponents.Empty();
	if (Voxel) {
		CellBounds = Voxel->CellBounds;
		Mesh = Voxel->Mesh;
		Cell = Voxel->Voxel;
		for (int32 i = 0; i < Mesh.Num(); ++i) {
			UInstancedStaticMeshComponent* Proxy = NewObject<UInstancedStaticMeshComponent>(this, NAME_None, RF_Transactional);
			Proxy->SetStaticMesh(Mesh[i]);
			Proxy->AttachTo(GetOwner()->GetRootComponent(), NAME_None);
			InstancedStaticMeshComponents.Add(Proxy);
		}
		AddVoxel();
	}
}
/** Calc Bounds */
FBoxSphereBounds UFluidSurfaceComponent::CalcBounds( const FTransform& LocalToWorld ) const
{
	FBoxSphereBounds NewBounds;
	/*if( BodySetup )
	{
	FBox AggGeomBox = BodySetup->AggGeom.CalcAABB( LocalToWorld );
	if( AggGeomBox.IsValid )
	{
	NewBounds = FBoxSphereBounds( AggGeomBox );
	}
	}
	else*/
	{
		FBox NewBox = FBox( FVector( -( ( FluidXSize * FluidGridSpacing ) / 2.0f ), -( ( FluidYSize * FluidGridSpacing ) / 2.0f ), -10.0f ), FVector( ( FluidXSize * FluidGridSpacing ) / 2.0f, ( FluidYSize * FluidGridSpacing ) / 2.0f, 10.0f ) );
		NewBounds = FBoxSphereBounds( NewBox );
		NewBounds.Origin = GetComponentLocation( );
	}

	return NewBounds;
}
/**
  * Calculates a tight box-sphere bounds for the aggregate geometry; this is more expensive than CalcAABB
  * (tight meaning the sphere may be smaller than would be required to encompass the AABB, but all individual components lie within both the box and the sphere)
  *
  * @param Output The output box-sphere bounds calculated for this set of aggregate geometry
  *	@param LocalToWorld Transform
  */
void FKAggregateGeom::CalcBoxSphereBounds(FBoxSphereBounds& Output, const FTransform& LocalToWorld) const
{
	// Calculate the AABB
	const FBox AABB = CalcAABB(LocalToWorld);

	if ((SphereElems.Num() == 0) && (SphylElems.Num() == 0) && (BoxElems.Num() == 0))
	{
		// For bounds that only consist of convex shapes (such as anything generated from a BSP model),
		// we can get nice tight bounds by considering just the points of the convex shape
		const FVector Origin = AABB.GetCenter();

		float RadiusSquared = 0.0f;
		for (int32 i = 0; i < ConvexElems.Num(); i++)
		{
			const FKConvexElem& Elem = ConvexElems[i];
			for (int32 j = 0; j < Elem.VertexData.Num(); ++j)
			{
				const FVector Point = LocalToWorld.TransformPosition(Elem.VertexData[j]);
				RadiusSquared = FMath::Max(RadiusSquared, (Point - Origin).SizeSquared());
			}
		}

		// Push the resulting AABB and sphere into the output
		AABB.GetCenterAndExtents(Output.Origin, Output.BoxExtent);
		Output.SphereRadius = FMath::Sqrt(RadiusSquared);
	}
	else if ((SphereElems.Num() == 1) && (SphylElems.Num() == 0) && (BoxElems.Num() == 0) && (ConvexElems.Num() == 0))
	{
		// For bounds that only consist of a single sphere,
		// we can be certain the box extents are the same as its radius
		AABB.GetCenterAndExtents(Output.Origin, Output.BoxExtent);
		Output.SphereRadius = Output.BoxExtent.X;
	}
	else
	{
		// Just use the loose sphere bounds that totally fit the AABB
		Output = FBoxSphereBounds(AABB);
	}
}
Esempio n. 21
0
void FSCSEditorViewportClient::RefreshPreviewBounds()
{
	AActor* PreviewActor = GetPreviewActor();

	if(PreviewActor)
	{
		// Compute actor bounds as the sum of its visible parts
		TInlineComponentArray<UPrimitiveComponent*> PrimitiveComponents;
		PreviewActor->GetComponents(PrimitiveComponents);

		PreviewActorBounds = FBoxSphereBounds(ForceInitToZero);
		for(auto CompIt = PrimitiveComponents.CreateConstIterator(); CompIt; ++CompIt)
		{
			// Aggregate primitive components that either have collision enabled or are otherwise visible components in-game
			UPrimitiveComponent* PrimComp = *CompIt;
			if(PrimComp->IsRegistered() && (!PrimComp->bHiddenInGame || PrimComp->IsCollisionEnabled()) && PrimComp->Bounds.SphereRadius < HALF_WORLD_MAX)
			{
				PreviewActorBounds = PreviewActorBounds + PrimComp->Bounds;
			}
		}
	}
}
FBoxSphereBounds UShapeComponent::CalcBounds(const FTransform& LocalToWorld) const
{
	check( false && "Subclass needs to Implement this" );
	return FBoxSphereBounds();
}
Esempio n. 23
0
FBoxSphereBounds UBoxComponent::CalcBounds(const FTransform& LocalToWorld) const 
{
	return FBoxSphereBounds( FBox( -BoxExtent, BoxExtent ) ).TransformBy(LocalToWorld);
}
bool SetApexDestructibleAsset(UDestructibleMesh& DestructibleMesh, NxDestructibleAsset& ApexDestructibleAsset, FSkeletalMeshImportData* OutData, EDestructibleImportOptions::Type Options)
{
	DestructibleMesh.PreEditChange(NULL);

	ExistingDestMeshData * ExistDestMeshDataPtr = SaveExistingDestMeshData(&DestructibleMesh);
	
	// The asset is going away, which will destroy any actors created from it.  We must destroy the physics state of any destructible mesh components before we release the asset.
	for(TObjectIterator<UDestructibleComponent> It; It; ++It)
	{
		UDestructibleComponent* DestructibleComponent = *It;
		if(DestructibleComponent->SkeletalMesh == &DestructibleMesh && DestructibleComponent->IsPhysicsStateCreated())
		{
			DestructibleComponent->DestroyPhysicsState();
		}
	}

	// Release old NxDestructibleAsset if it exists
	if (DestructibleMesh.ApexDestructibleAsset != NULL && DestructibleMesh.ApexDestructibleAsset != &ApexDestructibleAsset)
	{
		GPhysCommandHandler->DeferredRelease(DestructibleMesh.ApexDestructibleAsset);
	}

	// BRGTODO - need to remove the render data from the ApexDestructibleAsset, no longer need it
	// Removing const cast ... we'll have to make it non-const anyway when we modify it
	DestructibleMesh.ApexDestructibleAsset = &ApexDestructibleAsset;

	if ( !(Options&EDestructibleImportOptions::PreserveSettings) )
	{
		// Resize the depth parameters array to the appropriate size
		DestructibleMesh.DefaultDestructibleParameters.DepthParameters.Init(FDestructibleDepthParameters(), ApexDestructibleAsset.getDepthCount());

		// Resize the fracture effects array to the appropriate size
		DestructibleMesh.FractureEffects.AddZeroed(ApexDestructibleAsset.getDepthCount());

		// Load the UnrealEd-editable parameters from the destructible asset
		DestructibleMesh.LoadDefaultDestructibleParametersFromApexAsset();
	}
		
	// Create body setup for the destructible mesh
	DestructibleMesh.CreateBodySetup();

#if 0	// BRGTODO
	// warning for missing smoothing group info
	CheckSmoothingInfo(FbxMesh);
#endif
	
	FSkeletalMeshImportData TempData;
	// Fill with data from buffer
	FSkeletalMeshImportData* SkelMeshImportDataPtr = &TempData;
	if( OutData )
	{
		SkelMeshImportDataPtr = OutData;
	}
	
	// Get all material names here
	ImportMaterialsForSkelMesh(*SkelMeshImportDataPtr, ApexDestructibleAsset);

	// Import animation hierarchy, although this is trivial for an Apex Destructible Asset
	CreateBones(*SkelMeshImportDataPtr, ApexDestructibleAsset);

	// Import graphics data
	bool bHaveNormals, bHaveTangents;
	if (!FillSkelMeshImporterFromApexDestructibleAsset(*SkelMeshImportDataPtr, ApexDestructibleAsset, bHaveNormals, bHaveTangents))
	{
		return false;
	}

#if 0	// BRGTODO - what is this?
	if( SkelMeshImportDataPtr->Materials.Num() == FbxMatList.Num() )
	{
		// reorder material according to "SKinXX" in material name
		SetMaterialSkinXXOrder(*SkelMeshImportDataPtr, FbxMatList );
	}
#endif

#if 0	// BRGTODO - what is this?
	if( ImportOptions->bSplitNonMatchingTriangles )
	{
		DoUnSmoothVerts(*SkelMeshImportDataPtr);
	}
#endif

	// process materials from import data
	ProcessImportMeshMaterials( DestructibleMesh.Materials,*SkelMeshImportDataPtr );
	
	// process reference skeleton from import data
	int32 SkeletalDepth=0;
	if(!ProcessImportMeshSkeleton(DestructibleMesh.RefSkeleton, SkeletalDepth, *SkelMeshImportDataPtr))
	{
		return false;
	}
	UE_LOG(LogApexDestructibleAssetImport, Warning, TEXT("Bones digested - %i  Depth of hierarchy - %i"), DestructibleMesh.RefSkeleton.GetNum(), SkeletalDepth);

	// process bone influences from import data
	ProcessImportMeshInfluences(*SkelMeshImportDataPtr);

	FSkeletalMeshResource& DestructibleMeshResource = *DestructibleMesh.GetImportedResource();
	check(DestructibleMeshResource.LODModels.Num() == 0);
	DestructibleMeshResource.LODModels.Empty();
	new(DestructibleMeshResource.LODModels)FStaticLODModel();

	DestructibleMesh.LODInfo.Empty();
	DestructibleMesh.LODInfo.AddZeroed();
	DestructibleMesh.LODInfo[0].LODHysteresis = 0.02f;

	// Create initial bounding box based on expanded version of reference pose for meshes without physics assets. Can be overridden by artist.
	FBox BoundingBox(SkelMeshImportDataPtr->Points.GetData(), SkelMeshImportDataPtr->Points.Num());
	DestructibleMesh.Bounds= FBoxSphereBounds(BoundingBox);

	// Store whether or not this mesh has vertex colors
	DestructibleMesh.bHasVertexColors = SkelMeshImportDataPtr->bHasVertexColors;

	FStaticLODModel& LODModel = DestructibleMeshResource.LODModels[0];
	
	// Pass the number of texture coordinate sets to the LODModel.  Ensure there is at least one UV coord
	LODModel.NumTexCoords = FMath::Max<uint32>(1,SkelMeshImportDataPtr->NumTexCoords);
//	if( bCreateRenderData )	// We always create render data
	{
		// copy vertex data needed to generate skinning streams for LOD
		TArray<FVector> LODPoints;
		TArray<FMeshWedge> LODWedges;
		TArray<FMeshFace> LODFaces;
		TArray<FVertInfluence> LODInfluences;
		TArray<int32> LODPointToRawMap;
		SkelMeshImportDataPtr->CopyLODImportData(LODPoints,LODWedges,LODFaces,LODInfluences,LODPointToRawMap);

		IMeshUtilities& MeshUtilities = FModuleManager::Get().LoadModuleChecked<IMeshUtilities>("MeshUtilities");

		// Create actual rendering data.
		if (!MeshUtilities.BuildSkeletalMesh(DestructibleMeshResource.LODModels[0], DestructibleMesh.RefSkeleton, LODInfluences,LODWedges,LODFaces,LODPoints,LODPointToRawMap,false,!bHaveNormals,!bHaveTangents))
		{
			DestructibleMesh.MarkPendingKill();
			return false;
		}

		// Presize the per-section shadow casting array with the number of sections in the imported LOD.
		const int32 NumSections = LODModel.Sections.Num();

		for ( int32 SectionIndex = 0 ; SectionIndex < NumSections ; ++SectionIndex )
		{
			DestructibleMesh.LODInfo[0].TriangleSortSettings.AddZeroed();
		}

		if (ExistDestMeshDataPtr)
		{
			RestoreExistingDestMeshData(ExistDestMeshDataPtr, &DestructibleMesh);
			delete ExistDestMeshDataPtr;
			ExistDestMeshDataPtr = NULL;
		}

		DestructibleMesh.CalculateInvRefMatrices();
		DestructibleMesh.PostEditChange();
		DestructibleMesh.MarkPackageDirty();

#if 0 // BRGTODO : Check, we don't need this, do we?
		// We have to go and fix any AnimSetMeshLinkup objects that refer to this skeletal mesh, as the reference skeleton has changed.
		for(TObjectIterator<UAnimSet> It;It;++It)
		{
			UAnimSet* AnimSet = *It;

			// Get DestructibleMesh path name
			FName SkelMeshName = FName( *DestructibleMesh.GetPathName() );

			// See if we have already cached this Skeletal Mesh.
			const int32* IndexPtr = AnimSet->SkelMesh2LinkupCache.Find( SkelMeshName );

			if( IndexPtr )
			{
				AnimSet->LinkupCache( *IndexPtr ).BuildLinkup( &DestructibleMesh, AnimSet );
			}
		}
#endif

		// Now iterate over all skeletal mesh components re-initialising them.
		for(TObjectIterator<UDestructibleComponent> It; It; ++It)
		{
			UDestructibleComponent* DestructibleComponent = *It;
			if(DestructibleComponent->SkeletalMesh == &DestructibleMesh)
			{
				FComponentReregisterContext ReregisterContext(DestructibleComponent);
			}
		}
	}

#if INVERT_Y_AND_V
	// Apply transformation for Y inversion
	const physx::PxMat44 MirrorY = physx::PxMat44(physx::PxVec4(1.0f, -1.0f, 1.0f, 1.0f));
#if !USE_TEMPORARY_TRANSFORMATION_FUNCTION
	ApexDestructibleAsset.applyTransformation(MirrorY, 1.0f);
#else
	ApplyTransformationToApexDestructibleAsset( ApexDestructibleAsset, MirrorY );
#endif
#endif

	return true;
}
Esempio n. 25
0
FBoxSphereBounds ULineBatchComponent::CalcBounds( const FTransform& LocalToWorld ) const 
{
	const FVector BoxExtent(HALF_WORLD_MAX);
	return FBoxSphereBounds(FVector::ZeroVector, BoxExtent, BoxExtent.Size());
}
FBoxSphereBounds UFuncTestRenderingComponent::CalcBounds(const FTransform& LocalToWorld) const
{
	FBox BoundingBox = GetOwner()->GetComponentsBoundingBox();
	return FBoxSphereBounds(BoundingBox);
}
Esempio n. 27
0
FBoxSphereBounds UCapsuleComponent::CalcBounds(const FTransform& LocalToWorld) const
{
	FVector BoxPoint = FVector(CapsuleRadius,CapsuleRadius,CapsuleHalfHeight);
	return FBoxSphereBounds(FVector::ZeroVector, BoxPoint, BoxPoint.Size()).TransformBy(LocalToWorld);
}
Esempio n. 28
0
void ULightComponent::ReassignStationaryLightChannels(UWorld* TargetWorld, bool bAssignForLightingBuild)
{
	TMap<FLightAndChannel*, TArray<FLightAndChannel*> > LightToOverlapMap;

	// Build an array of all static shadowing lights that need to be assigned
	for(TObjectIterator<ULightComponent> LightIt(RF_ClassDefaultObject|RF_PendingKill); LightIt; ++LightIt)
	{
		ULightComponent* const LightComponent = *LightIt;

		const bool bLightIsInWorld = LightComponent->GetOwner() && TargetWorld->ContainsActor(LightComponent->GetOwner()) && !LightComponent->GetOwner()->IsPendingKill();

		if (bLightIsInWorld 
			// Only operate on stationary light components (static shadowing only)
			&& LightComponent->HasStaticShadowing()
			&& !LightComponent->HasStaticLighting())
		{
			if (LightComponent->bAffectsWorld
				&& LightComponent->CastShadows 
				&& LightComponent->CastStaticShadows)
			{
				LightToOverlapMap.Add(new FLightAndChannel(LightComponent), TArray<FLightAndChannel*>());
			}
			else
			{
				// Reset the preview channel of stationary light components that shouldn't get a channel
				// This is necessary to handle a light being newly disabled
				LightComponent->PreviewShadowMapChannel = INDEX_NONE;

#if WITH_EDITOR
				LightComponent->UpdateLightSpriteTexture();
#endif
			}
		}
	}

	// Build an array of overlapping lights
	for (TMap<FLightAndChannel*, TArray<FLightAndChannel*> >::TIterator It(LightToOverlapMap); It; ++It)
	{
		ULightComponent* CurrentLight = It.Key()->Light;
		TArray<FLightAndChannel*>& OverlappingLights = It.Value();

		if (bAssignForLightingBuild)
		{
			// This should have happened during lighting invalidation at the beginning of the build anyway
			CurrentLight->ShadowMapChannel = INDEX_NONE;
		}

		for (TMap<FLightAndChannel*, TArray<FLightAndChannel*> >::TIterator OtherIt(LightToOverlapMap); OtherIt; ++OtherIt)
		{
			ULightComponent* OtherLight = OtherIt.Key()->Light;

			if (CurrentLight != OtherLight 
				// Testing both directions because the spotlight <-> spotlight test is just cone vs bounding sphere
				//@todo - more accurate spotlight <-> spotlight intersection
				&& CurrentLight->AffectsBounds(FBoxSphereBounds(OtherLight->GetBoundingSphere()))
				&& OtherLight->AffectsBounds(FBoxSphereBounds(CurrentLight->GetBoundingSphere())))
			{
				OverlappingLights.Add(OtherIt.Key());
			}
		}
	}
		
	// Sort lights with the most overlapping lights first
	LightToOverlapMap.ValueSort(FCompareLightsByArrayCount());

	TMap<FLightAndChannel*, TArray<FLightAndChannel*> > SortedLightToOverlapMap;

	// Add directional lights to the beginning so they always get channels
	for (TMap<FLightAndChannel*, TArray<FLightAndChannel*> >::TIterator It(LightToOverlapMap); It; ++It)
	{
		FLightAndChannel* CurrentLight = It.Key();

		if (CurrentLight->Light->GetLightType() == LightType_Directional)
		{
			SortedLightToOverlapMap.Add(It.Key(), It.Value());
		}
	}

	// Add everything else, which has been sorted by descending overlaps
	for (TMap<FLightAndChannel*, TArray<FLightAndChannel*> >::TIterator It(LightToOverlapMap); It; ++It)
	{
		FLightAndChannel* CurrentLight = It.Key();

		if (CurrentLight->Light->GetLightType() != LightType_Directional)
		{
			SortedLightToOverlapMap.Add(It.Key(), It.Value());
		}
	}

	// Go through lights and assign shadowmap channels
	//@todo - retry with different ordering heuristics when it fails
	for (TMap<FLightAndChannel*, TArray<FLightAndChannel*> >::TIterator It(SortedLightToOverlapMap); It; ++It)
	{
		bool bChannelUsed[4] = {0};
		FLightAndChannel* CurrentLight = It.Key();
		const TArray<FLightAndChannel*>& OverlappingLights = It.Value();

		// Mark which channels have already been assigned to overlapping lights
		for (int32 OverlappingIndex = 0; OverlappingIndex < OverlappingLights.Num(); OverlappingIndex++)
		{
			FLightAndChannel* OverlappingLight = OverlappingLights[OverlappingIndex];

			if (OverlappingLight->Channel != INDEX_NONE)
			{
				bChannelUsed[OverlappingLight->Channel] = true;
			}
		}

		// Use the lowest free channel
		for (int32 ChannelIndex = 0; ChannelIndex < ARRAY_COUNT(bChannelUsed); ChannelIndex++)
		{
			if (!bChannelUsed[ChannelIndex])
			{
				CurrentLight->Channel = ChannelIndex;
				break;
			}
		}
	}

	// Go through the assigned lights and update their render state and icon
	for (TMap<FLightAndChannel*, TArray<FLightAndChannel*> >::TIterator It(SortedLightToOverlapMap); It; ++It)
	{
		FLightAndChannel* CurrentLight = It.Key();

		if (CurrentLight->Light->PreviewShadowMapChannel != CurrentLight->Channel)
		{
			CurrentLight->Light->PreviewShadowMapChannel = CurrentLight->Channel;
			CurrentLight->Light->MarkRenderStateDirty();
		}

#if WITH_EDITOR
		CurrentLight->Light->UpdateLightSpriteTexture();
#endif

		if (bAssignForLightingBuild)
		{
			CurrentLight->Light->ShadowMapChannel = CurrentLight->Channel;

			if (CurrentLight->Light->ShadowMapChannel == INDEX_NONE)
			{
				FMessageLog("LightingResults").Error()
					->AddToken(FUObjectToken::Create(CurrentLight->Light->GetOwner()))
					->AddToken(FTextToken::Create( NSLOCTEXT("Lightmass", "LightmassError_FailedToAllocateShadowmapChannel", "Severe performance loss: Failed to allocate shadowmap channel for stationary light due to overlap - light will fall back to dynamic shadows!") ) );
			}
		}

		delete CurrentLight;
	}
}
Esempio n. 29
0
FBoxSphereBounds UArrowComponent::CalcBounds(const FTransform & LocalToWorld) const
{
	return FBoxSphereBounds(FBox(FVector(0,-ARROW_SCALE,-ARROW_SCALE),FVector(ArrowSize * ARROW_SCALE * 3.0f,ARROW_SCALE,ARROW_SCALE))).TransformBy(LocalToWorld);
}
FBoxSphereBounds UEQSRenderingComponent::CalcBounds(const FTransform& LocalToWorld) const
{
	static FBox BoundingBox(FVector(-HALF_WORLD_MAX), FVector(HALF_WORLD_MAX));
	return FBoxSphereBounds(BoundingBox);
}