C++ 粒子沉积地形生成
我用粒子沉积的方法,尝试在程序上创造一些火山状的山脉,但我从中得到的只是金字塔状的结构。任何熟悉算法的人都可能会发现我可能做错了什么。我现在把每个粒子放在同一个地方。如果我不知道的话,它们会分布在一个非常薄的层中,而不是任何一种山C++ 粒子沉积地形生成,c++,terrain,procedural-generation,C++,Terrain,Procedural Generation,我用粒子沉积的方法,尝试在程序上创造一些火山状的山脉,但我从中得到的只是金字塔状的结构。任何熟悉算法的人都可能会发现我可能做错了什么。我现在把每个粒子放在同一个地方。如果我不知道的话,它们会分布在一个非常薄的层中,而不是任何一种山 void TerrainClass::ParticalDeposition(int loops){ float height = 0.0; //for(int k= 0; k <10; k++){ int dropX = mCurrentX =
void TerrainClass::ParticalDeposition(int loops){
float height = 0.0;
//for(int k= 0; k <10; k++){
int dropX = mCurrentX = rand()%(m_terrainWidth-80) + 40;
int dropY = mCurrentZ = rand()%(m_terrainHeight-80) + 40;
int radius = 15;
float angle = 0;
int tempthing = 0;
loops = 360;
for(int i = 0; i < loops; i++){
mCurrentX = dropX + radius * cos(angle);
mCurrentZ = dropY + radius * sin(angle);
/*f(i%loops/5 == 0){
dropX -= radius * cos(angle);
dropY += radius * sin(angle);
angle+= 0.005;
mCurrentX = dropX;
mCurrentZ = dropY;
}*/
angle += 360/loops;
//dropX += rand()%5;
//dropY += rand()%5;
//for(int j = 0; j < loops; j++){
float newY = 0;
newY = (1 - (2.0f/loops)*i);
if(newY < 0.0f){
newY = 0.0f;
}
DepositParticle(newY);
//}
}
//}
}
void TerrainClass::DepositParticle(float heightIncrease){
bool posFound = false;
m_lowerList.clear();
while(posFound == false){
int offset = 10;
int jitter;
if(Stable(0.5f)){
m_heightMap[(m_terrainHeight*mCurrentZ)+mCurrentX].y += heightIncrease;
posFound = true;
}else{
if(!m_lowerList.empty()){
int element = rand()%m_lowerList.size();
int lowerIndex = m_lowerList.at(element);
MoveTo(lowerIndex);
}
}
}
}
bool TerrainClass::Stable(float deltaHeight){
int index[9];
float height[9];
index[0] = ((m_terrainHeight*mCurrentZ)+mCurrentX); //the current index
index[1] = ValidIndex((m_terrainHeight*mCurrentZ)+mCurrentX+1) ? (m_terrainHeight*mCurrentZ)+mCurrentX+1 : -1; // if the index to the right is valid index set index[] to index else set index[] to -1
index[2] = ValidIndex((m_terrainHeight*mCurrentZ)+mCurrentX-1) ? (m_terrainHeight*mCurrentZ)+mCurrentX-1 : -1; //to the left
index[3] = ValidIndex((m_terrainHeight*(mCurrentZ+1))+mCurrentX) ? (m_terrainHeight*(mCurrentZ+1))+mCurrentX : -1; // above
index[4] = ValidIndex((m_terrainHeight*(mCurrentZ-1))+mCurrentX) ? (m_terrainHeight*(mCurrentZ-1))+mCurrentX : -1; // bellow
index[5] = ValidIndex((m_terrainHeight*(mCurrentZ+1))+mCurrentX+1) ? (m_terrainHeight*(mCurrentZ+1))+mCurrentX+1: -1; // above to the right
index[6] = ValidIndex((m_terrainHeight*(mCurrentZ-1))+mCurrentX+1) ? (m_terrainHeight*(mCurrentZ-1))+mCurrentX+1: -1; // below to the right
index[7] = ValidIndex((m_terrainHeight*(mCurrentZ+1))+mCurrentX-1) ? (m_terrainHeight*(mCurrentZ+1))+mCurrentX-1: -1; // above to the left
index[8] = ValidIndex((m_terrainHeight*(mCurrentZ-1))+mCurrentX-1) ? (m_terrainHeight*(mCurrentZ-1))+mCurrentX-1: -1; // above to the right
for ( int i = 0; i < 9; i++){
height[i] = (index[i] != -1) ? m_heightMap[index[i]].y : -1;
}
m_lowerList.clear();
for(int i = 1; i < 9; i++){
if(height[i] != -1){
if(height[i] < height[0] - deltaHeight){
m_lowerList.push_back(index[i]);
}
}
}
return m_lowerList.empty();
}
bool TerrainClass::ValidIndex(int index){
return (index > 0 && index < m_terrainWidth*m_terrainHeight) ? true : false;
}
void TerrainClass::MoveTo(int index){
mCurrentX = index%m_terrainWidth;
mCurrentZ = index/m_terrainHeight;
}
void TerrainClass::ParticalDeposition(int循环){
浮动高度=0.0;
//对于(int k=0;k 0&&index
这就是所有使用的代码 如果希望粒子不扩散到单层中,则粒子的物理模型中需要有一些表面摩擦和/或粘性(或类似)。更新粒子模拟时,这将在代码的碰撞检测和碰撞响应部分执行 一种简单的方法是使粒子粘附(相互吸引)。粒子也需要有一个大小,这样它们就不会简单地收敛到完全重叠的位置。如果要使它们相互吸引,则需要测试粒子之间的距离。 您可能会从浏览使用粒子的DirectX SDK示例中获益,特别是(Pun ARF),在英伟达GPU计算SDK中有一个很棒的演示(Simon Green),它实现了CUDA中的粘性粒子。它包括一个自述文件,描述他们所做的事情。如果你不打算进行大规模粒子计数,你可以看到粒子如何相互作用,忽略所有CUDA/GPU的东西 还请注意,一旦使用粒子间力,那么您将检查大约0.5*n^2个粒子组合(对)…因此您可能需要使用简单的空间分割方案或类似方案,以仅将力限制到附近的粒子组。
祝你好运 你应该看看这两篇论文: (先读第一个,第二个展开) 不要被“在GPU上”吓到,这些算法在CPU上运行得很好(尽管速度较慢)。这些算法本身不做粒子沉降(但你也不做;)-它们将粒子聚合成几层向量场 该算法的一个重要特点是,它会侵蚀现有的高度贴图,例如使用生成的高度贴图。如果初始高度场完全平坦(或者即使高度变化不足),它也会失败 我自己实现了这个算法,并且取得了很大的成功(还有更多的工作要做,这些算法很难平衡,以产生普遍的好结果)-见下图 请注意,使用第二张纸中的热风化组件可能对您来说已经足够了(并且可能会为您节省很多麻烦)
您也可以在C++的CPU中实现这一算法(特别是GPL许可证),并简化其在我的.
页的24-29页上的描述。哇。这太神奇了。去年我在一门算法课程上做了一个小项目,我希望我知道你的项目。你的论文似乎很有趣,我希望我有时间把它全部读一遍。在zlib许可证下,以防任何人对许可证更宽松的东西感兴趣。至少从截图上看,你的结果比德卡丁的要好,我非常钦佩他的作品。很不错的。