Problems with using TOctree

Hello Everybody,

So I have been studying how TOctree is used in PrimitiveSceneInfo.h and NavigationOctree.h, but I am still horribly confused on how to get it to work. The links above should take you to their respective pages on Github.

I have a Quadrant class where I have tried creating OctreeSemantics and OctreeElements structs which can be seen below. I am able to build my solution without errors but when I try to build the editor I get this error message.

Question: Could someone give a simple working example of how to use the TOctree template?

My Code:

struct FQuadrantOctreeElement
{
	AActor MyActor;
	FBoxSphereBounds Bounds;
};

struct FQuadrantOctreeSematics
{
	enum { MaxElementsPerLeaf = 16 };
	enum { MinInclusiveElementsPerNode = 7 };
	enum { MaxNodeDepth = 12 };

	typedef TInlineAllocator<MaxElementsPerLeaf> ElementAllocator;

	FORCEINLINE static const FBoxSphereBounds& GetBoundingBox(const FQuadrantOctreeElement& QuadrantOctreeElement)
	{
		return QuadrantOctreeElement.Bounds;
	}
};

Any help is greatly appreciated,

Farshooter

Looks like the bug is on this line:

UE4Editor_ProceduralTerrain!AQuadrant::AQuadrant() [c:\users\ben\documents\unreal projects\proceduralterrain\source\proceduralterrain\quadrant.cpp:9]

Something with the constructor VTable if that error is correct. Can you post that constructor?

This is my constructor.

// Sets default values
AQuadrant::AQuadrant()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

}

It’s pretty simple.

Can you post the header file for AQuadrant? My guess is your missing a call to Super in your constructor, or TOctree base class.

Just to give you the complete picture, I will post my header and source here. I had to zip them into a folder because Answerhub won’t let you post header and source files individually.

Okay, so yea, I think what your constructor isn’t properly setup and calling to your AActor base classes constructor.

Try this:

In Quadrant.h

UCLASS()
class PROCEDURALTERRAIN_API AQuadrant : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AQuadrant(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());

	// Called when the game starts or when spawned
	virtual void BeginPlay() override;
	
	// Called every frame
	virtual void Tick( float DeltaSeconds ) override;

private:

	// TOctree<FQuadrantOctreeElement, FQuadrantOctreeSematics> Data;
	
};

In Quadrant.cpp

// Sets default values
AQuadrant::AQuadrant(const FObjectInitializer& ObjectInitializer)
 : Super(ObjectInitializer)
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

}

You need to call Super because it allows the base class to initialize all its variables properly and do any work it needs before constructing your inherited object.

Thanks you for the help @AdeptStrain. That allowed me to compile and build the editor just fine. I just have one more problem. I removed the comment from the line of code below and now I can compile, but I get this error message when trying to build the editor. I feel like if we can solve this problem then I can start using the TOctree class.

Code that I removed the comment from in my header:

// TOctree<FQuadrantOctreeElement, FQuadrantOctreeSematics> Data;

Do you have any ideas? I am thinking that there might be something that I am missing in my FQuadrantOctreeElement struct or my FQuadrantOctreeSematics struct, but that is purely a guess because I am not one hundred percent sure how they work.

The Default TOctree constructor (which is what it’ll use unless you specify another one) is not meant to be used, so that’s why you’re getting that message. The constructor you want takes in an FVector for the origin of the Octree and then a radius value.

So you need to change your Quadrant constructor code like so:

 AQuadrant::AQuadrant(const FObjectInitializer& ObjectInitializer)
  : Super(ObjectInitializer)
  , Data(FVector(0.0f, 0.0f, 0.0f), 100.0f) // Origin and Radius, put your own values here.
 {
      // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
     PrimaryActorTick.bCanEverTick = true;
 
 }

That did it. Thank you @AdeptStrain for all your help. Now that it is working I just need to play with the TOctree type to understand it better and figure out what exactly it is doing.

I do have one more question about the modifications that were made to the constructor, but I am going to post it here to keep this post on topic.

Thanks again,

Farshooter