I updated to newst Ogre version (the version with vulcan). I also updated to newest Terra version carefully. I made some sanity tests, if everything is working. But now, when I modify terra, the data structure is modified correctly, as ray-casts are working correctly and I even see changes in the heightmap, but the terrain itself is not growing anymore. It remains flat. See the attached video:
http://www.lukas-kalinowski.com/Homepag ... yIssue.mp4
What could cause this?
I use 3 functions for modifcation: start (create staging texture), modify (pixmap), finish (staging texture).
Code: Select all
void Terra::modifyTerrainStart(const Ogre::Vector3& position, float strength)
{
m_oldHeightData.resize(m_width * m_depth, 0);
m_newHeightData.resize(m_width * m_depth, 0);
TextureGpuManager* textureManager = mManager->getDestinationRenderSystem()->getTextureGpuManager();
// Important: Only create once, and after that work on that staging texture, else the heights get resetted every time
if (nullptr == m_heightMapStagingTexture)
{
m_heightMapStagingTexture = textureManager->getStagingTexture(m_heightMapTex->getWidth(), m_heightMapTex->getHeight(), 1u, 1u, m_heightMapTex->getPixelFormat());
}
m_heightMapStagingTexture->startMapRegion();
TextureBox texBox = m_heightMapStagingTexture->mapRegion(m_heightMapTex->getWidth(), m_heightMapTex->getHeight(), 1u, 1u, m_heightMapTex->getPixelFormat());
memcpy(&m_oldHeightData[0], texBox.data, m_heightMapStagingTexture->_getSizeBytes());
m_heightMapStagingTexture->stopMapRegion();
this->applyHeightDiff(position, m_brushData, m_brushSize, strength);
}
void Terra::applyHeightDiff(const Ogre::Vector3& position, const std::vector<float>& data, int boxSize, float strength)
{
if (data.size() != boxSize * boxSize)
return;
// assert(data.size() == boxSize * boxSize);
Ogre::GridPoint point = this->worldToGrid(position);
//Offset the box so that the corner isn't the centre.
point.x -= boxSize / 2;
point.z -= boxSize / 2;
int x = point.x;
int y = point.z;
TextureGpuManager* textureManager = mManager->getDestinationRenderSystem()->getTextureGpuManager();
// Important: Only create once, and after that work on that staging texture, else the heights get resetted every time
if (nullptr == m_heightMapStagingTexture)
{
m_heightMapStagingTexture = textureManager->getStagingTexture(m_heightMapTex->getWidth(), m_heightMapTex->getHeight(), 1u, 1u, m_heightMapTex->getPixelFormat());
}
if (m_heightMapTex->getNextResidencyStatus() != Ogre::GpuResidency::Resident)
{
m_heightMapTex->_transitionTo(Ogre::GpuResidency::Resident, (Ogre::uint8*)0);
m_heightMapTex->_setNextResidencyStatus(Ogre::GpuResidency::Resident);
}
m_heightMapStagingTexture->startMapRegion();
TextureBox texBox = m_heightMapStagingTexture->mapRegion(m_heightMapTex->getWidth(), m_heightMapTex->getHeight(), 1u, 1u, m_heightMapTex->getPixelFormat());
float fBpp = (float)(PixelFormatGpuUtils::getBytesPerPixel(m_heightMapTex->getPixelFormat()) << 3u);
const float maxValue = powf(2.0f, fBpp) - 1.0f;
m_invMaxValue = 1.0f / maxValue;
uint32 movAmount;
uint32 shouldMoveAmount;
int boxStartX, boxStartY, boxWidth, boxHeight;
_calculateBoxSpecification(x, y, boxSize, m_heightMapTex->getWidth(), m_heightMapTex->getHeight(), &movAmount, &shouldMoveAmount, &boxStartX, &boxStartY, &boxWidth, &boxHeight);
if (m_heightMapTex->getPixelFormat() == PFG_R16_UNORM)
{
for (int by = boxStartY; by < boxHeight; by++)
{
unsigned int posY = y + by;
uint16* RESTRICT_ALIAS pixBoxData = reinterpret_cast<uint16 * RESTRICT_ALIAS>(texBox.at(0, posY, 0));
for (int bx = boxStartX; bx < boxWidth; bx++)
{
unsigned int posX = x + bx;
uint16 oldValue = pixBoxData[posX];
float determinedValue = oldValue + data[by * boxSize + bx] * strength;
if (determinedValue < 0.0f)
{
determinedValue = 0.0f;
}
//If value is 0 (we're lowering the terrain), the value should never be greater than what it previously was (possible with integer wrap-arounds).
if (strength < 0 && determinedValue > oldValue)
{
determinedValue = 0;
}
else if (strength > 0 && determinedValue < oldValue)
{
determinedValue = heightToVal<float>(m_height);
}
pixBoxData[posX] = determinedValue;
const float targetValue = this->valToHeight<float>(determinedValue);
m_heightMap[movAmount] = targetValue;
movAmount++;
}
movAmount += shouldMoveAmount; //Align to the start of the next line.
}
}
m_heightMapStagingTexture->stopMapRegion();
m_heightMapStagingTexture->upload(texBox, m_heightMapTex, 0, 0, 0);
if (false == m_heightMapTex->isDataReady())
m_heightMapTex->notifyDataIsReady();
// is this necessary?
updateHeightTextures();
calculateOptimumSkirtSize();
}
std::pair<std::vector<Ogre::uint16>, std::vector<Ogre::uint16>> Terra::modifyTerrainFinished(void)
{
TextureGpuManager* textureManager = mManager->getDestinationRenderSystem()->getTextureGpuManager();
// Important: Only create once, and after that work on that staging texture, else the heights get resetted every time
if (nullptr == m_heightMapStagingTexture)
{
m_heightMapStagingTexture = textureManager->getStagingTexture(m_heightMapTex->getWidth(), m_heightMapTex->getHeight(), 1u, 1u, m_heightMapTex->getPixelFormat());
}
m_heightMapStagingTexture->startMapRegion();
TextureBox texBox = m_heightMapStagingTexture->mapRegion(m_heightMapTex->getWidth(), m_heightMapTex->getHeight(), 1u, 1u, m_heightMapTex->getPixelFormat());
memcpy(&m_newHeightData[0], texBox.data, m_heightMapStagingTexture->_getSizeBytes());
m_heightMapStagingTexture->stopMapRegion();
return std::move(std::make_pair(m_oldHeightData, m_newHeightData));
}
Lax