ALCCActorBase : classe de base des Actors 3DGS
Classe de base de tous les Actors LCC, chargée de placer les données 3DGS dans le niveau. ALCCActor, ALCC2Actor, ASogActor, ASpzActor et APlyActor en héritent tous.
| Module | LCC4UnrealRuntime |
| En-tête | LCCActorBase.h |
| Classe parente | AActor |
| Blueprint | Héritable (BlueprintType) |
#include "LCCActorBase.h"
L'Actor lui-même n'effectue aucun rendu : il détient un ULCCComponentBase et lui transmet les opérations de chargement. Les paramètres de rendu, la couleur, la performance et la collision se trouvent tous sur le Component, obtenu via GetLCCComponent.
Limite sur la mise à l'échelle : les Actors de la famille LCC ne prennent en charge qu'une mise à l'échelle uniforme. Ne pas utiliser d'échelle avec des valeurs négatives (comme
(-1, 1, 1)) ni d'échelle différente selon les axes (comme(2, 1, 3)), sinon des anomalies de rendu apparaissent, qui se manifestent généralement par une simple ligne à l'écran.
Propriétés
| Propriété | Type | Accès | Description |
|---|---|---|---|
DefaultSceneRoot | ULCCFocusRootComponent* | Lecture seule | Composant racine invisible. Son unique raison d'être est de donner au viewport de l'éditeur une petite boîte englobante fixe, afin que la mise au point avec F continue de fonctionner même dans une scène immense. |
LCCComponent | ULCCComponentBase* | Lecture seule | Le composant qui fait le vrai travail. Son type concret est déterminé lors de la construction de la sous-classe. |
Les deux propriétés sont VisibleAnywhere + BlueprintReadOnly : elles ne peuvent être remplacées ni dans le panneau Details ni dans Blueprint, seulement lues.
Méthodes
Load
UFUNCTION(BlueprintCallable, Category = "XGrids")
virtual void Load(const FString& String) const;
Charge des données 3DGS depuis un chemin. C'est le point d'entrée principal pour charger une scène à l'exécution.
Paramètres :
| Paramètre | Type | Description |
|---|---|---|
String | const FString& | Chemin du fichier de données. Les chemins absolus (D:/Data/Tower/Tower.lcc) et relatifs sont tous deux pris en charge. Les chemins relatifs sont résolus par rapport au répertoire Content du projet, Tower/Tower.lcc pointe donc vers Content/Tower/Tower.lcc. |
La forme de chemin acceptée diffère selon la sous-classe :
| Actor | Ce qu'il faut passer |
|---|---|
ALCCActor | Chemin d'un fichier LCC1 .lcc. Le nom du fichier n'est pas fixe, et data.bin et index.bin doivent se trouver dans le même répertoire |
ALCC2Actor | Chemin d'un fichier LCC2 .lcc2. Le nom du fichier n'est pas fixe |
ASogActor | Chemin d'un fichier .sog |
ASpzActor | Chemin d'un fichier .spz |
APlyActor | Chemin d'un fichier .ply ; une extension autre que .ply est rejetée immédiatement |
Note : les noms des fichiers
.lccet.lcc2sont déterminés par la production des données, ne pas supposer que le fichier s'appelle toujoursmeta.lcc. Déterminer le format d'après l'extension, ou avec ULCCUtilLibrary::DetermineFileFormat.
Points d'utilisation :
- La méthode est
const, car le changement d'état a lieu à l'intérieur deLCCComponentet l'Actor lui-même n'est pas modifié. - Le chargement est asynchrone. Au retour de l'appel, les données ne sont pas encore prêtes, et la version actuelle exige une interrogation avec
GetLCCComponent()->CheckIfLoaded(). Un callback de fin de chargement sera fourni dans une version ultérieure, l'interrogation ne sera alors plus nécessaire. - Si
CheckIfLoaded()renvoietrue, cela signifie seulement que les métadonnées et l'index sont construits et que les paramètres peuvent être lus et configurés sans risque ; les données de splats continuent d'être diffusées selon le point de vue et l'image continue de se compléter. - Pour prédéfinir un chemin dans le niveau sans écrire de code, régler directement
DefaultLoadPathdu Component dans le panneau Details ; il sera chargé automatiquement à l'exécution. - Passer un chemin vide équivaut à décharger les données actuelles.
- Si le chemin passé est identique au chemin actuellement chargé, l'appel retourne immédiatement et rien n'est rechargé.
- En cas de chemin douteux, le valider d'abord avec ULCCUtilLibrary::CheckLCCValid, afin qu'un échec de chargement ne se limite pas à un message dans le journal.
Exemple C++ :
#include "LCCActor.h"
#include "LCCComponentBase.h"
void AMyGameMode::SpawnLCCScene()
{
// Spawn the Actor
ALCCActor* LCCActor = GetWorld()->SpawnActor<ALCCActor>(
ALCCActor::StaticClass(),
FVector::ZeroVector,
FRotator::ZeroRotator);
if (!LCCActor)
{
return;
}
// Load from an absolute path
LCCActor->Load(TEXT("D:/Data/Tower/Tower.lcc"));
// Or load relative to the Content directory
// LCCActor->Load(TEXT("Tower/Tower.lcc"));
}
Attendre la fin du chargement avant de manipuler les données. La version actuelle n'a pas de callback, l'interrogation est donc la seule possibilité :
void AMyActor::LoadAndConfigure()
{
LCCActor->Load(TEXT("D:/Data/Tower/Tower.lcc"));
// Check readiness every 0.2 seconds
GetWorld()->GetTimerManager().SetTimer(
LoadCheckTimer, this, &AMyActor::OnCheckLoaded, 0.2f, true);
}
void AMyActor::OnCheckLoaded()
{
ULCCComponentBase* Component = LCCActor->GetLCCComponent();
if (!Component || !Component->CheckIfLoaded())
{
return;
}
GetWorld()->GetTimerManager().ClearTimer(LoadCheckTimer);
// Metadata is ready, parameters can be configured safely (splat data is still streaming)
Component->SetRenderMode(ERenderMode::Splatting);
UE_LOG(LogTemp, Log, TEXT("Total splats: %d"), Component->GetSplatNumber());
}
Blueprint sous forme de texte :
[Event BeginPlay]
│
▼
[Spawn Actor from Class]
Class = LCCActor
Spawn Transform = (default)
│ Return Value ──┐
▼ │
[Load] ◀────────────────┘
Target = (Return Value of the previous step)
String = "D:/Data/Tower/Tower.lcc"
UnLoad
UFUNCTION(BlueprintCallable, CallInEditor, Category = "Actions",
meta = (DisplayName = "UnLoad", DisplayPriority = 2))
virtual void UnLoad();
Décharge les données actuelles et libère les ressources, dont les tampons de mémoire vidéo, les caches de nœuds et les corps de collision.
Points d'utilisation :
- Avec
CallInEditor, un bouton UnLoad apparaît sous la catégorie Actions du panneau Details et peut être cliqué directement dans l'éditeur. - Après le déchargement, l'Actor reste dans le niveau, il ne rend simplement plus rien. Un nouvel appel à
Loadpermet de charger d'autres données. - Lors d'un changement de grande scène, appeler
UnLoadavantLoad, afin que deux jeux de données n'occupent pas la mémoire vidéo en même temps. - Un appel manuel dans
EndPlayn'est pas nécessaire ; le Component se nettoie lui-même à sa destruction.
Exemple C++ de changement de scène :
void AMyManager::SwitchScene(const FString& NewPath)
{
// Release the old data first, so that video memory peaks do not add up
LCCActor->UnLoad();
LCCActor->Load(NewPath);
}
Refresh
UFUNCTION(BlueprintCallable, CallInEditor, Category = "Actions",
meta = (DisplayPriority = 3))
virtual void Refresh();
Recharge les données actuelles. En interne, UnLoad() est exécuté puis Load(), le coût correspond donc à un rechargement complet et ce n'est pas une opération légère.
Le rechargement des données « actuelles » est possible parce qu'un chargement réussi écrit aussi le chemin dans DefaultLoadPath, et Refresh lit cette valeur.
Points d'utilisation :
- L'utiliser pour relire le disque après que les fichiers de données du disque ont été remplacés.
- Ne pas l'utiliser pour faire recalculer le résultat du rendu. Modifier une propriété via son setter déclenche automatiquement une mise à jour ; pour pousser une seule image, utiliser
ForceUpdate()du Component, qui est l'option légère. - Après le rechargement, il faut de nouveau attendre que les données soient prêtes, et les paramètres d'exécution réglés auparavant sur le Component doivent éventuellement être redéfinis.
- Dans l'éditeur, un bouton correspondant apparaît sous la catégorie Actions du panneau Details.
GetLCCComponent
UFUNCTION(BlueprintCallable, Category = "XGrids")
ULCCComponentBase* GetLCCComponent() const;
Renvoie le pointeur vers le Component interne de l'Actor. C'est le point d'entrée vers toutes les capacités de rendu.
Valeur de retour : ULCCComponentBase*. En conditions normales, non nul, car il est créé lors de la construction de l'Actor.
Points d'utilisation :
- Un transtypage descendant est nécessaire lorsqu'une capacité propre à une sous-classe est requise.
ALCCActorfournit unULCCComponent, tandis queALCC2Actoret les trois Actors de fichier unique fournissent unULCC2Component. - Toujours transtyper avec
Cast<>, jamais avec une conversion de style C.Castrenvoienullptren cas de type incompatible, ce qui facilite une sortie anticipée.
Exemple C++ de modification des paramètres communs de la classe de base :
ULCCComponentBase* Component = LCCActor->GetLCCComponent();
if (Component)
{
Component->SetSplatScale(0.8f);
Component->SetGlobalAlpha(1.0f);
}
Transtypage descendant pour atteindre les paramètres propres à LCC2 :
#include "LCC2Component.h"
ULCC2Component* LCC2Comp = Cast<ULCC2Component>(LCC2Actor->GetLCCComponent());
if (LCC2Comp)
{
LCC2Comp->SetSHBands(2);
LCC2Comp->NormalMode = ELCC2NormalGenerationMode::Hemispherical;
}
Blueprint sous forme de texte ; le transtypage dans Blueprint utilise un node Cast To :
[Get LCC Component]
Target = LCCActor
│ Return Value ──┐
▼ │
[Cast To LCC2Component] ◀┘
Object = (Return Value of the previous step)
│ Cast Succeeded
▼
[Set SH Bands]
Target = (As LCC2 Component output of the Cast)
In SH Bands = 2
SelectFile
UFUNCTION(BlueprintCallable, CallInEditor, Category = "Actions",
meta = (DisplayName = "Load", DisplayPriority = 1))
virtual void SelectFile();
Ouvre la boîte de dialogue de sélection de fichier du système et charge immédiatement la sélection.
Points d'utilisation :
- Elle s'affiche comme un bouton Load dans le panneau Details et constitue la manière la plus courante de charger des données dans l'éditeur.
- Chaque sous-classe la redéfinit pour filtrer l'extension correspondante :
ASogActorne liste que.sog,ASpzActorque.spz,APlyActorque.ply. - Elle dépend des capacités de dialogue de l'éditeur, donc ne pas l'utiliser dans un exécutable packagé ; à l'exécution, utiliser Load à la place.
DebugNodeBound
UFUNCTION(BlueprintCallable, CallInEditor, Category = "Actions",
meta = (DisplayName = "Debug Node Bound", DisplayPriority = 4))
void DebugNodeBound();
Active ou désactive la visualisation des limites des nœuds de l'octree, en dessinant les nœuds actuellement chargés sous forme de boîtes filaires.
La couleur des boîtes correspond au Level du nœud : rouge, orange, jaune, vert, bleu et violet dans cet ordre, le rouge étant le Level le plus bas (détail le plus élevé) et le blanc le Level le plus haut (détail le plus faible).
Points d'utilisation :
- L'utiliser pour analyser les problèmes de LOD. Des boîtes rouges encore rendues au loin signifient que
LevelFactorest trop petit ou queStartLevelest réglé trop bas, et que de la performance est gaspillée. - À l'inverse, des boîtes de couleur froide à Level élevé à proximité signifient que le détail est trop fortement réduit et que l'image paraît floue.
- Un nouvel appel la désactive ; c'est un commutateur.
- Effective uniquement dans l'éditeur et dans les builds Development.
Stats
UFUNCTION(BlueprintCallable, CallInEditor, Category = "Actions",
meta = (DisplayPriority = 5))
void Stats();
Active ou désactive le panneau de statistiques de rendu, équivaut à exécuter stat XGrids dans la console.
Le panneau donne le nombre de splats rendus actuellement, le nombre de nœuds en cours de chargement et le temps passé à chaque étape. Ajuster les paramètres de performance en l'observant est plus fiable qu'un réglage à l'intuition.
ShowCollision
UFUNCTION(BlueprintCallable, CallInEditor, Category = "Actions",
meta = (DisplayName = "Show Collision", DisplayPriority = 6))
void ShowCollision();
Active ou désactive la visualisation filaire de la collision, équivaut à exécuter r.xgrids.DrawCollision dans la console.
Points d'utilisation :
- Elle suppose que les données comportent elles-mêmes de la collision et que
bEnableCollisiondu Component est activé, sinon rien ne s'affiche. - L'activer en premier quand un personnage traverse la géométrie ou qu'un test de rayon ne touche rien, afin de confirmer si les corps de collision ont bien été chargés.
- La collision est diffusée en fonction de la distance, l'absence de filaire au loin est donc un comportement normal, contrôlé par
Performance.CollisionLoadMaxDistance.
ShowFPS
UFUNCTION(BlueprintCallable, CallInEditor, Category = "Actions",
meta = (DisplayName = "Show FPS", DisplayPriority = 7))
void ShowFPS();
Active ou désactive l'affichage de la fréquence d'images, équivaut à exécuter stat fps dans la console. À utiliser avec Stats pour observer côte à côte la fréquence d'images et le nombre de splats.
Exemple complet
Charger une scène LCC à l'exécution et configurer les paramètres de rendu dès qu'elle est prête :
// MyLCCLoader.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyLCCLoader.generated.h"
UCLASS()
class AMyLCCLoader : public AActor
{
GENERATED_BODY()
public:
/** Data path to load, absolute or relative to the Content directory */
UPROPERTY(EditAnywhere, Category = "MyLCC")
FString ScenePath = TEXT("Tower/Tower.lcc");
protected:
virtual void BeginPlay() override;
private:
void OnLoadCheck();
UPROPERTY()
TObjectPtr<class ALCCActor> LCCActor;
FTimerHandle LoadCheckTimer;
};
// MyLCCLoader.cpp
#include "MyLCCLoader.h"
#include "LCCActor.h"
#include "LCCComponentBase.h"
void AMyLCCLoader::BeginPlay()
{
Super::BeginPlay();
LCCActor = GetWorld()->SpawnActor<ALCCActor>(
ALCCActor::StaticClass(), GetActorTransform());
if (!LCCActor)
{
return;
}
LCCActor->Load(ScenePath);
GetWorld()->GetTimerManager().SetTimer(
LoadCheckTimer, this, &AMyLCCLoader::OnLoadCheck, 0.2f, true);
}
void AMyLCCLoader::OnLoadCheck()
{
ULCCComponentBase* Component = LCCActor ? LCCActor->GetLCCComponent() : nullptr;
if (!Component || !Component->CheckIfLoaded())
{
return;
}
GetWorld()->GetTimerManager().ClearTimer(LoadCheckTimer);
// Metadata is ready, configure as needed
Component->SetRenderMode(ERenderMode::Splatting);
Component->SetSplatScale(0.9f);
Component->SetMaxDistance(200); // render up to 200 meters
Component->SetMaxSplatNum(1500); // at most 15 million splats per frame
Component->SetLCCCollisionEnable(true);
UE_LOG(LogTemp, Log, TEXT("LCC ready, splat number: %d"),
Component->GetSplatNumber());
}
Voir aussi
- ULCCComponentBase : les paramètres de rendu et de performance se trouvent ici
- Actors SOG / SPZ / PLY : Actors dédiés aux trois formats de fichier unique
- ULCCUtilLibrary : validation du chemin et du format avant le chargement