Hi all!
I’m trying to dynamically update Landscape components during runtime, but hit a wall and need some help.
Here’s what I got so far.
void ATerrainImporter::CreateTerrain()
{
// Generate 8x8 array with height 65000
uint16 *Heights;
GenerateHeights(8, 8, 65000, &Heights);
for (TActorIterator<ALandscapeProxy> ActorItr(GetWorld()); ActorItr; ++ActorItr)
{
TArray<ULandscapeHeightfieldCollisionComponent*> Components = ActorItr->CollisionComponents;
for (int c = 0; c < Components.Num(); c++)
{
UpdateTexture(Components[c]->RenderComponent->HeightmapTexture, Heights);
//UpdateCollision(Components[c], Heights);
}
}
delete] Heights;
}
The visible height of the terrain DOES change, but appears completely black and stops casting shadow (even with only Movable light sources).
Unfortunately, I can’t find a way to update the colliders - function ‘UpdateCollision’ is the closest I could get to finding what seemed collision related, but doesn’t work and can randomly crash the editor.
Landscape->Import(…) is a no-go, since it only works inside editor.
Any ideas?
void UpdateTexture(UTexture2D *InTexture, uint16 *InSource)
{
for (int m = 0; m < InTexture->PlatformData->Mips.Num(); m++)
{
uint16 *Dest = (uint16*)InTexture->PlatformData->Mips[m].BulkData.Lock(LOCK_READ_WRITE);
// How many pixels to advance for given Mip level
uint16 StepX = (uint16)pow(2.0f, m);
uint16 StepY = (StepX - 1) * InTexture->PlatformData->Mips[0].SizeX;
for (uint16 y = 0; y < InTexture->PlatformData->Mips[m].SizeY; y++, InSource += StepY)
for (uint16 x = 0; x < InTexture->PlatformData->Mips[m].SizeX; x++, InSource += StepX)
{
*(Dest++) = *InSource;
// No idea what the reverse is used for, but doesn't work otherwise
*(Dest++) = Reverse(*InSource);
}
// Reset Source
InSource -= InTexture->PlatformData->Mips[0].SizeX * InTexture->PlatformData->Mips[0].SizeY;
InTexture->PlatformData->Mips[m].BulkData.Unlock();
}
InTexture->UpdateResource();
}
void UpdateCollision(ULandscapeHeightfieldCollisionComponent* InComponent, uint16 *InSource)
{
uint16 *Dest = (uint16*)InComponent->CollisionHeightData.Lock(LOCK_READ_WRITE);
for (int i = 0; i < InComponent->CollisionHeightData.GetElementCount(); i++, InSource++, Dest++)
*Dest = *InSource;
InComponent->CollisionHeightData.Unlock();
// Editor only
//Components[c]->UpdateHeightfieldRegion(0, 0, 1, 1);
}