[英]Problems with the box example in Frank Luna's introduction to his book '3D game programming with DirectX12'
[英]In an example code of the book “introduction to 3d game programming with directx 11”
void GeometryGenerator::Subdivide(MeshData& meshData)
{
// Save a copy of the input geometry.
MeshData inputCopy = meshData;
meshData.Vertices.resize(0);
meshData.Indices.resize(0);
// v1
// *
// / \
// / \
// m0*-----*m1
// / \ / \
// / \ / \
// *-----*-----*
// v0 m2 v2
UINT numTris = inputCopy.Indices.size()/3;
for(UINT i = 0; i < numTris; ++i)
{
Vertex v0 = inputCopy.Vertices[ inputCopy.Indices[i*3+0] ];
Vertex v1 = inputCopy.Vertices[ inputCopy.Indices[i*3+1] ];
Vertex v2 = inputCopy.Vertices[ inputCopy.Indices[i*3+2] ];
//
// Generate the midpoints.
//
Vertex m0, m1, m2;
// For subdivision, we just care about the position component. We
// derive the other
// vertex components in CreateGeosphere.
m0.Position = XMFLOAT3(
0.5f*(v0.Position.x + v1.Position.x),
0.5f*(v0.Position.y + v1.Position.y),
0.5f*(v0.Position.z + v1.Position.z));
m1.Position = XMFLOAT3(
0.5f*(v1.Position.x + v2.Position.x),
0.5f*(v1.Position.y + v2.Position.y),
0.5f*(v1.Position.z + v2.Position.z));
m2.Position = XMFLOAT3(
0.5f*(v0.Position.x + v2.Position.x),
0.5f*(v0.Position.y + v2.Position.y),
0.5f*(v0.Position.z + v2.Position.z));
//
// Add new geometry.
//
meshData.Vertices.push_back(v0); // 0
meshData.Vertices.push_back(v1); // 1
meshData.Vertices.push_back(v2); // 2
meshData.Vertices.push_back(m0); // 3
meshData.Vertices.push_back(m1); // 4
meshData.Vertices.push_back(m2); // 5
meshData.Indices.push_back(i*6+0);
meshData.Indices.push_back(i*6+3);
meshData.Indices.push_back(i*6+5);
meshData.Indices.push_back(i*6+3);
meshData.Indices.push_back(i*6+4);
meshData.Indices.push_back(i*6+5);
meshData.Indices.push_back(i*6+5);
meshData.Indices.push_back(i*6+4);
meshData.Indices.push_back(i*6+2);
meshData.Indices.push_back(i*6+3);
meshData.Indices.push_back(i*6+1);
meshData.Indices.push_back(i*6+4);
}
}
此函數在'GeometryGenerator.cpp'文件中,並且可以細分網格。 在調用此功能之前,將創建一個二十面體並將其作為參數meshData進行傳輸。 MeshData,頂點和索引的成員是STL的向量。
在我看來,在此函數調用了一系列函數meshData.Vertices.push_back之后,在循環的下一次迭代中,可能會重復存儲一些頂點。
任何人都可以回答
謝謝所有讀我英語不好的人。
我是否錯
我很確定你是對的 ,尤其是關於重復的頂點!
為什么作者制作這樣的代碼
除了作者本人之外,沒有人可以回答這個問題。 我想他/她只是監督了重復問題...
或者如果我的想法正確,是否有更有效的方法。
只要算法不正確,我就不會在乎效率!
首先,我們需要避免頂點重復。 我只是將現有的頂點保持不變(因此僅clear
索引),並在最后附加新的頂點。 為此,我將邊緣存儲在臨時std :: map中,將一對索引(邊緣)映射到新創建的索引(始終先使用較小的索引,以避免(10,12)
與(12,10)
,它標識同一條邊...)。
然后對於v0,v1,v2,我將使用索引,而不是頂點本身。 首先在地圖上查找m0,m1,m2,如果找到,請使用,否則,創建一個新頂點,將其添加到頂點向量中,然后在我們的地圖中添加一個條目。
UINT v0 = copiedIndices[i*3+0];
// ...
UINT m0;
auto key = std::make_pair(v0, v1); // TODO: order indices!!!
auto entry = myMap.find(key);
if(entry != myMap.end())
{
m0 = entry->second;
}
else
{
meshData.Vertices.push_back(newVertex);
m0 = meshData.Vertices.size() - 1;
myMap.insert(key, m0);
}
然后,您將添加新的三角形,只需按原樣使用索引:
meshdata.indices.pushback(v0); // one of the original indices
meshdata.indices.pushback(m0); // one of the new ones
meshdata.indices.pushback(m2);
// ...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.