void PhysicalTile::updatePxHeight() { // do the physx update only when needed if (m_pxUpdateBox.maxColumn < m_pxUpdateBox.minColumn) return; PxHeightFieldGeometry geometry; bool result = m_pxShape->getHeightFieldGeometry(geometry); assert(result); if (!result) { glow::warning("TerrainInteractor::setPxHeight could not get height field geometry from physx shape"); return; } PxHeightField * hf = geometry.heightField; assert(m_pxUpdateBox.minRow <= m_pxUpdateBox.maxRow && m_pxUpdateBox.minColumn <= m_pxUpdateBox.maxColumn); unsigned int nbRows = m_pxUpdateBox.maxRow - m_pxUpdateBox.minRow + 1; unsigned int nbColumns = m_pxUpdateBox.maxColumn - m_pxUpdateBox.minColumn + 1; unsigned int fieldSize = nbRows * nbColumns; PxHeightFieldSample * samplesM = new PxHeightFieldSample[fieldSize]; for (unsigned int r = 0; r < nbRows; ++r) { unsigned int rowOffset = r * nbColumns; for (unsigned int c = 0; c < nbColumns; ++c) { const unsigned int index = c + rowOffset; const unsigned int tileValueIndex = (c + m_pxUpdateBox.minColumn) + (r + m_pxUpdateBox.minRow) * samplesPerAxis; const float terrainHeight = valueAt(tileValueIndex); samplesM[index].height = static_cast<PxI16>(terrainHeight / geometry.heightScale); samplesM[index].materialIndex0 = samplesM[index].materialIndex1 = elementIndexAt(tileValueIndex); } } PxHeightFieldDesc descM; descM.nbColumns = nbColumns; descM.nbRows = nbRows; descM.samples.data = samplesM; descM.format = hf->getFormat(); descM.samples.stride = hf->getSampleStride(); descM.thickness = hf->getThickness(); descM.convexEdgeThreshold = hf->getConvexEdgeThreshold(); descM.flags = hf->getFlags(); PhysicsWrapper::getInstance()->pauseGPUAcceleration(); bool success = hf->modifySamples(m_pxUpdateBox.minColumn, m_pxUpdateBox.minRow, descM); assert(success); if (!success) { glow::warning("TerrainInteractor::setPxHeight could not modify height field."); return; } PxHeightFieldGeometry newGeometry(hf, PxMeshGeometryFlags(), geometry.heightScale, geometry.rowScale, geometry.columnScale); assert(PxGetPhysics().getNbScenes() == 1); PxScene * pxScenePtrs[1]; PxGetPhysics().getScenes(pxScenePtrs, 1); pxScenePtrs[0]->lockWrite(); m_pxShape->setGeometry(newGeometry); pxScenePtrs[0]->unlockWrite(); PhysicsWrapper::getInstance()->restoreGPUAccelerated(); #ifdef PX_WINDOWS if (PhysicsWrapper::getInstance()->physxGpuAvailable()) { PxParticleGpu::releaseHeightFieldMirror(*hf); PxParticleGpu::createHeightFieldMirror(*hf, *PhysicsWrapper::getInstance()->cudaContextManager()); } #endif clearPxBufferUpdateRange(); }