2013-11-11 8 views
0

я следующий код для вычисления HeightMap нормалейНормального усреднения высот

void CalcMapNormals(HeightMap * map, Vec3f normals[]) 
{ 
int  dst, i, j, right, bottom; 
Vec3f p0, p1, p2; 
Vec3f n0; 

/* Avoid writing map->rows|cols - 1 all the time */ 
right = map->cols - 1; 
bottom = map->rows - 1; 

dst = 0; 
for (i = 0; i < map->rows; i++) { 
    for (j = 0; j < map->cols; j++) { 
     Vec3Set(normals[dst], 0, 0, 0); 
     /* Vertex can have 2, 3, or 4 neighbours horizontally and vertically */ 
     if (i < bottom && j < right) { 
      /* Right and below */ 
      GetHeightPoint(map, i, j, p0); 
      GetHeightPoint(map, i + 1, j, p1); 
      GetHeightPoint(map, i + 1, j + 1, p2); 
      CalcTriNormal(n0, p0, p1, p2); 
      VecAdd(normals[dst], normals[dst], n0); 
     } 
     /* TODO: the other three possibilities */ 
     VecNormalize(normals[dst]); 
     dst += 1; 
    } 
} 
/* Sanity check */ 
if (dst != map->rows * map->cols) 
    Fail("Internal error in CalcMapNormals: normals count mismatch"); 
} 

Я понимаю, что код получить три вершины треугольника, вычислить его нормальным, а затем добавить их и нормализовать их, чтобы получить в среднем нормальным , Но я не знаю, как вы можете получить другие три возможности, ив делал что-то вроде следующего:

void CalcMapNormals(HeightMap * map, Vec3f normals[]) 
{ 
int  dst, i, j, right, bottom; 
Vec3f p0, p1, p2; 
Vec3f n0; 
Vec3f p3, p4, p5; 
Vec3f n1; 
Vec3f p6, p7, p8; 
Vec3f n2; 
Vec3f p9, p10, p11; 
Vec3f n3; 
/* Avoid writing map->rows|cols - 1 all the time */ 
right = map->cols - 1; 
bottom = map->rows - 1; 

dst = 0; 
for (i = 0; i < map->rows; i++) { 
    for (j = 0; j < map->cols; j++) { 
     Vec3Set(normals[dst], 0, 0, 0); 
     /* Vertex can have 2, 3, or 4 neighbours horizontally and vertically */ 
     if (i < bottom && j < right) { 
      /* Right and below */ 
      GetHeightPoint(map, i, j, p0); 
      GetHeightPoint(map, i + 1, j, p1); 
      GetHeightPoint(map, i + 1, j + 1, p2); 
      CalcTriNormal(n0, p0, p1, p2); 
      VecAdd(normals[dst], normals[dst], n0); 
     } 
     if (i > bottom && j > 0) 
     { 
      GetHeightPoint(map, i, j, p3); 
      GetHeightPoint(map, i + 1, j, p4); 
      GetHeightPoint(map, i, j -1, p5); 
      CalcTriNormal(n1, p3, p4, p5); 
      VecAdd(normals[dst], normals[dst], n1); 
     } 
     if (i > 0 && j > 0) 
     { 
      GetHeightPoint(map, i, j, p6); 
      GetHeightPoint(map, i, j - 1, p7); 
      GetHeightPoint(map, i - 1, j, p8); 
      CalcTriNormal(n2, p6, p7, p8); 
      VecAdd(normals[dst], normals[dst], n2); 

     } 
     if (i > bottom && j < right) 
     { 

      GetHeightPoint(map, i, j, p9); 
      GetHeightPoint(map, i-1, j, p10); 
      GetHeightPoint(map, i, j+1, p11); 
      CalcTriNormal(n3, p9, p10, p11); 
      VecAdd(normals[dst], normals[dst], n3); 
     } 
     /* TODO: the other three possibilities */ 
     VecNormalize(normals[dst]); 
     dst += 1; 
    } 
} 
/* Sanity check */ 
if (dst != map->rows * map->cols) 
    Fail("Internal error in CalcMapNormals: normals count mismatch"); 
} 

Но я не думаю, что его дает мне результат я хотел, я получить понятие о нормальной усреднение, но не может определить код.

+0

Итак, вы ищете нормальное значение для каждой вершины или одного на треугольник? Просто чтобы уточнить, я имею в виду, поэтому я могу ответить кратко. Причина, о которой я прошу, заключается в том, что похоже, что вы пытаетесь получить нормали всех трех вершин треугольника, а затем усреднить их, что было бы таким же, как нормальное для треугольник. – GMasucci

+0

@GMasucci Спасибо, я пытаюсь получить усредненную нормальную для каждой вершины, в основном я пытаюсь получить все соседние треугольники, которые разделяют вершину (до 6 треугольников можно разделить вершину, я использую 4) и получить средний нормальный, извините, если я не объясню это ясно. – Mindless

ответ

1

Привет Yzwboy вот один способ, которым я хотел бы попробовать сделать «сглаженные» нормали (усредненный на основе соседних треугольников):

Для того, чтобы вычислить «сглаженные» нормали вам нужно будет присвоить каждую вершину нормального, который усредняется по нормалям треугольников, смежных с вершиной.

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

Псевдокод:

Vec3F faceNormal(int face_id, int vertex_id) // assumes C-->B-->A is clockwise 
{ 
    Vec3f A = triangleMesh.face[face_id].vertex[vertex_id];  // A 
    Vec3f B = triangleMesh.face[face_id].vertex[(vertex_id+1)%3]; // B 
    Vec3f C = triangleMesh.face[face_id].vertex[(vertex_id+2)%3]; // C 
    Vec3f BA = B-A; 
    Vec3f CA = C-A; 
    Vec3f Normal = BA.cross(CA); 

    float sin_alpha = length(Normal)/(BA.len() * CA.len()); // depending on your implementation of Vec3f it could be .magnitude() or .length() instead of .len() 
    return (Normal.normalize() * asin(sin_alpha);) 
} 

И затем изменить нормальный по вершине:

void computeNormals() { 
    for (vertex v in triangleMesh) 
    { 
     Vec3f Normal (0,0,0); 
     for (int i = 0;i < TriangleCount;i++) 
      if (triangleMesh.face[i].contains(v)) 
      { 
       int vertID = vertexPositionInTriangle(i,v); //Can be 0,1 or 2. Use an enum to make A = 0, B=1, C=2 if that is easier to read:) 
       Normal = Normal + faceNormal(i,vertID); 
      } 
     addNormalToVertexV(Normal.normalize(),v); // this is a function to set the normal for a vertex, the vertex class must have a member for normal though and the arguments for the function are Vec3f, Vec3f 
    } 
} 

Вы также можете вычислить площадь каждого треугольника, чтобы использовать s взвешивание, хотя я нахожу, что использование углов лучше всего подходит для взглядов в большинстве случаев.

Я попытался использовать имена, соответствующие спецификации Vec3f, а также встроенные функции для сохранения работы, но вам нужно будет сделать некоторую кодировку, чтобы заставить псевдокод работать (у меня нет доступа к среде тестирования GL здесь) ,

Надеюсь, что это поможет :)

+0

дайте мне знать, если вы снова застряли, и я постараюсь помочь :) – GMasucci

+0

Спасибо, я понял, сейчас, попрошу еще раз, если возникнут вопросы :) – Mindless