2016-05-26 2 views
1

Я реализовал алгоритм маршевого куба в среде DirectX (тестировать и получать удовольствие). По завершении я заметил, что результирующая модель выглядит сильно искаженной, как если бы показатели были отключены.DirectX/C++: индексирование маршевых кубов

enter image description here

Я попытался извлечь индексы, но я думаю, что вершины упорядочены правильно уже, используя поисковые таблицы, примеры на http://paulbourke.net/geometry/polygonise/. Текущая сборка использует громкость 15^3.

Маршевые кубов перебирает массив как обычно:

for (float iX = 0; iX < CellFieldSize.x; iX++){ 
    for (float iY = 0; iY < CellFieldSize.y; iY++){ 
     for (float iZ = 0; iZ < CellFieldSize.z; iZ++){ 
      MarchCubes(XMFLOAT3(iX*StepSize, iY*StepSize, iZ*StepSize), StepSize); 
     } 
    } 
} 

Функция MarchCube называется:

void MC::MarchCubes(){ 

... 

int Corner, Vertex, VertexTest, Edge, Triangle, FlagIndex, EdgeFlags; 
float Offset; 
XMFLOAT3 Color; 
float CubeValue[8]; 
XMFLOAT3 EdgeVertex[12]; 
XMFLOAT3 EdgeNorm[12]; 

//Local copy 
for (Vertex = 0; Vertex < 8; Vertex++) { 
    CubeValue[Vertex] = (this->*fSample)(
     in_Position.x + VertexOffset[Vertex][0] * Scale, 
     in_Position.y + VertexOffset[Vertex][1] * Scale, 
     in_Position.z + VertexOffset[Vertex][2] * Scale 
); 
} 

FlagIndex = 0; 

перекрестков расчеты:

... 
//Test vertices for intersection. 
for (VertexTest = 0; VertexTest < 8; VertexTest++){ 
    if (CubeValue[VertexTest] <= TargetValue) 
     FlagIndex |= 1 << VertexTest; 
} 

//Find which edges are intersected by the surface. 
EdgeFlags = CubeEdgeFlags[FlagIndex]; 
if (EdgeFlags == 0){ 
    return; 
} 

for (Edge = 0; Edge < 12; Edge++){ 
    if (EdgeFlags & (1 << Edge)) { 
     Offset = GetOffset(CubeValue[EdgeConnection[Edge][0]], CubeValue[EdgeConnection[Edge][1]], TargetValue); // Get offset function definition. Needed! 
     EdgeVertex[Edge].x = in_Position.x + VertexOffset[EdgeConnection[Edge][0]][0] + Offset * EdgeDirection[Edge][0] * Scale; 
     EdgeVertex[Edge].y = in_Position.y + VertexOffset[EdgeConnection[Edge][0]][1] + Offset * EdgeDirection[Edge][1] * Scale; 
     EdgeVertex[Edge].z = in_Position.z + VertexOffset[EdgeConnection[Edge][0]][2] + Offset * EdgeDirection[Edge][2] * Scale; 

     GetNormal(EdgeNorm[Edge], EdgeVertex[Edge].x, EdgeVertex[Edge].y, EdgeVertex[Edge].z); //Need normal values 
    } 
} 

И оригинальная реализация получает толкнул в холдинговая структура для DirectX.

for (Triangle = 0; Triangle < 5; Triangle++) { 

    if (TriangleConnectionTable[FlagIndex][3 * Triangle] < 0) break; 

    for (Corner = 0; Corner < 3; Corner++) { 
     Vertex = TriangleConnectionTable[FlagIndex][3 * Triangle + Corner];3 * Triangle + Corner]); 
     GetColor(Color, EdgeVertex[Vertex], EdgeNorm[Vertex]); 
     Data.VertexData.push_back(XMFLOAT3(EdgeVertex[Vertex].x, EdgeVertex[Vertex].y, EdgeVertex[Vertex].z)); 
     Data.NormalData.push_back(XMFLOAT3(EdgeNorm[Vertex].x, EdgeNorm[Vertex].y, EdgeNorm[Vertex].z)); 
     Data.ColorData.push_back(XMFLOAT4(Color.x, Color.y, Color.z, 1.0f)); 
    } 
} 

(Это тот же порядок, как в оригинальной реализации GL)

+0

Я полагаю, что сегодня вечером я посмотрю новый взгляд. –

ответ

0

Оказывается, я пропустил скобку, показывая оператору приоритет.

EdgeVertex[Edge].x = in_Position.x + (VertexOffset[EdgeConnection[Edge][0]][0] + Offset * EdgeDirection[Edge][0]) * Scale; 
    EdgeVertex[Edge].y = in_Position.y + (VertexOffset[EdgeConnection[Edge][0]][1] + Offset * EdgeDirection[Edge][1]) * Scale; 
    EdgeVertex[Edge].z = in_Position.z + (VertexOffset[EdgeConnection[Edge][0]][2] + Offset * EdgeDirection[Edge][2]) * Scale; 

Исправлено, получено Visine; возобновленная забава.

Смежные вопросы