Модераторы: Rickert

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Свой 3D формат, я запутался... 
:(
    Опции темы
DragonFire
Дата 1.1.2007, 19:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 725
Регистрация: 14.8.2005
Где: Москва

Репутация: 5
Всего: 9



ZC1989
Долго силился вникнуть в код но понятно только в общих чертах, т.к. сам пишу на Delphi (тут не особенно проблем) и OpenGL (а вот директа не совсем ясна).

Я так понял ты сначало задаешь все вершины с нормалями в буфер, потом его отрисовываешь. По 
причине, описанной выше точно сказать не могу почему так, но есть идея одна.
Возможно ты к двем треугольникам лежащим в одной плоскости строишь разные нормали. Одну как бы "вверх", другую "вниз". У меня была такая проблема. Все зависит от последовательности вершин, пихаемых в функцию.  

На всякий случай приведу свой код, который у меня работает верно:
Код

 for i:=1 to Count do begin
    glBegin(GL_TRIANGLES);
      Normal:=Normal3D(
      vertexes[planes[i][0]].x,vertexes[planes[i][0]].y,vertexes[planes[i][0]].z,
      vertexes[planes[i][1]].x,vertexes[planes[i][1]].y,vertexes[planes[i][1]].z,
      vertexes[planes[i][2]].x,vertexes[planes[i][2]].y,vertexes[planes[i][2]].z
      );
      glNormal3f(Normal.X,Normal.Y,Normal.Z);
      glVertex3f(vertexes[planes[i][0]].x,vertexes[planes[i][0]].y,vertexes[planes[i][0]].z);
      glVertex3f(vertexes[planes[i][1]].x,vertexes[planes[i][1]].y,vertexes[planes[i][1]].z);
      glVertex3f(vertexes[planes[i][2]].x,vertexes[planes[i][2]].y,vertexes[planes[i][2]].z);
    glEnd;
  end;

Тут Normal это просто вектор, тоесть посути запись x,y,z:extended...


--------------------
PM MAIL ICQ   Вверх
ZC1989
Дата 1.1.2007, 19:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 468
Регистрация: 17.7.2006
Где: Нижний Новгород; Россия

Репутация: нет
Всего: 1



DragonFire,  так у меня то же вектор это 3 координты (xyz, ijk... как угодно) просто на именно этой грани такая запарка, но о последовательности я уверен что она зде правильно описана (против часово)... ладно, с другими гранями вроде нормально, возможно просто точку у одного увело вниз... буду искать сам... потом расскажу об успехах smile 


--------------------
озарение настанет позже, когда поймём больше... (Сo. Stigmata)
PM MAIL ICQ   Вверх
DragonFire
Дата 1.1.2007, 20:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 725
Регистрация: 14.8.2005
Где: Москва

Репутация: 5
Всего: 9



А как в директе источник света задается? Может дело в нем?


--------------------
PM MAIL ICQ   Вверх
ZC1989
Дата 1.1.2007, 20:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 468
Регистрация: 17.7.2006
Где: Нижний Новгород; Россия

Репутация: нет
Всего: 1



DragonFire, нет, сет не даёт ошибки 100%, это что-то с нормалью или моделью...

но всё равно, вот мой свет
Код

D3DLIGHT9                    plight;
D3DXVECTOR3                    vecDir;
...
    // LIGHT'S
    pDevice -> SetRenderState(D3DRS_LIGHTING, TRUE);
    ZeroMemory (&plight, sizeof(D3DLIGHT9));
    plight.Type = D3DLIGHT_DIRECTIONAL;
    plight.Diffuse.r  = 0.85f;
    plight.Diffuse.g  = 0.85f;
    plight.Diffuse.b  = 0.85f;
    plight.Range = 1000.0f;

    vecDir = D3DXVECTOR3(Px, Py - 700, Pz - 100);
    D3DXVec3Normalize((D3DXVECTOR3*)&plight.Direction, &vecDir);
    pDevice -> SetLight(0, &plight);
    pDevice -> LightEnable(0, true);



--------------------
озарение настанет позже, когда поймём больше... (Сo. Stigmata)
PM MAIL ICQ   Вверх
ZC1989
Дата 1.1.2007, 21:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 468
Регистрация: 17.7.2006
Где: Нижний Новгород; Россия

Репутация: нет
Всего: 1



DragonFire, извини за флуд! я прав был, это не ошибки расчётов, просто парень рисовавшый объект смустил точки! с нормалями всё О.К. но всёж спасибо! smile 


--------------------
озарение настанет позже, когда поймём больше... (Сo. Stigmata)
PM MAIL ICQ   Вверх
DragonFire
Дата 2.1.2007, 01:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 725
Регистрация: 14.8.2005
Где: Москва

Репутация: 5
Всего: 9



Ура ура)))


--------------------
PM MAIL ICQ   Вверх
ZC1989
Дата 3.1.2007, 21:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 468
Регистрация: 17.7.2006
Где: Нижний Новгород; Россия

Репутация: нет
Всего: 1



Решил последовать совету и перевёл все точки в один буфер, потом, разобрался с матрицами, теперь могу делать в пяти строчках все, что мне нужно было, оч удобно! На радостях решил загрузить один файлик, там описан «микроб», состоит он из 22000 полигонов, собс-но это где-то 66000 точек.
Перевёл в свой формат, всё пучком, когда загружается сцена, получается такая фишка, что нельзя разом увидеть этот «микроб», его попросту нет на экране, но если повертеть камерой так что в кадре не весь он будет, а половина, то он начинает отрисовываться… от чего такая кривизна, от того что это один объект целиковый или я что-то нафлудил?

ЗЫ: грубо говоря «микроб» это сфера с торчащими из неё ножками, оч похожа на мину глубоководную со времён ВМВ.



--------------------
озарение настанет позже, когда поймём больше... (Сo. Stigmata)
PM MAIL ICQ   Вверх
ZC1989
Дата 3.1.2007, 22:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 468
Регистрация: 17.7.2006
Где: Нижний Новгород; Россия

Репутация: нет
Всего: 1



Bitter, а мне тут вспомнился такой метод работы с нормалями, когда не к плоскости нормаль одна, в следствии чего все 3 точки плоскости имеют одну и ту же нрмаль, а когда для этих трёх точек нормали разные, что даёт более сглаженные границы соединения швов между траинглами...

 это я вот к чему, ты писал что нормали в ASE описанные не верны, но может этот как раз тот случай когда для каждой точки нормали раные? тем более, если не ошибаюсь, ты говорил нормали "испортятся" если сферу повернуть, но, помоему, они и должны будут поменяться!

есть в этом бредовом рассуждении хоть капля здравого смысла? smile 


--------------------
озарение настанет позже, когда поймём больше... (Сo. Stigmata)
PM MAIL ICQ   Вверх
Bitter
Дата 4.1.2007, 03:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный лентяй
***


Профиль
Группа: Завсегдатай
Сообщений: 1209
Регистрация: 15.8.2004
Где: Харьков, Ukraine

Репутация: 5
Всего: 27



smile  Всё это конечно, правильно. Но дело как раз в том, что при повороте сферы нормали НЕ меняются. В этом и есть запара. Т.е. объект поворачивается, а нормали нет. По этому приходится их расчитывать самому. А вообще, конечно, надо для каждой точки свою нормаль иметь. По этому шарики всегда получаются круглыми (сглаженными), даже при малых кол-вах полигонов. 
По моему в доке, который я тебе присылал, есть описание подобъекта, так вот там как раз каждая точка имеет свою нормаль. Если надо, выложу код для расчета сглаженных нормалей по заданному углу (например, сглаживать, если угол <50 градусов). Но он на Delphi (хотя можно попробовать в словесной форме написать код).
PM MAIL ICQ Skype   Вверх
ZC1989
Дата 4.1.2007, 11:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 468
Регистрация: 17.7.2006
Где: Нижний Новгород; Россия

Репутация: нет
Всего: 1



Bitter, я мутно представляю как для точек расчитывать, так что буду раб! и в словесной форме, как-то лучше получается, хоть сразу знаю что делать надо...

+ у меня проблемы какие-то при экспорте в ASE, объект получается инвертирован слева-на-право, и поднят на 90 градусов


--------------------
озарение настанет позже, когда поймём больше... (Сo. Stigmata)
PM MAIL ICQ   Вверх
DragonFire
Дата 4.1.2007, 12:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 725
Регистрация: 14.8.2005
Где: Москва

Репутация: 5
Всего: 9



Цитата(Bitter @  4.1.2007,  03:34 Найти цитируемый пост)
Если надо, выложу код для расчета сглаженных нормалей по заданному углу (например, сглаживать, если угол <50 градусов). Но он на Delphi (хотя можно попробовать в словесной форме написать код). 

Выложи плиз))


--------------------
PM MAIL ICQ   Вверх
Nicholas_S
Дата 4.1.2007, 14:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 486
Регистрация: 12.10.2006
Где: Санкт-Петербург

Репутация: нет
Всего: 19



ZC1989, для справки: когда каждая грань объекта имеет 1 нормаль, обычно происходит плоская закраска (flat); гладкие закраски (гуро, фонга, последний точнее и заметно лучше выглядит) происходят из расчета того, что каждая точка грани имеет свою нормаль.

При модификации объекта (повороте, непропорциональном сжатии/растяжении) массив нормалей должен соответственно быть модифицирован.
Можно пересчитывать нормали при трансформации каждый раз.
Нахождение нормали к грани можно получить следующим образом:
Код

   For i := 0 to FacesCnt-1 do 
   begin
     tVector1 := FVertexes[FFaces[i].v1];
     tVector2 := FVertexes[FFaces[i].v2];
     tVector3 := FVertexes[FFaces[i].v3];

     vx1 := tVector1.x - tVector2.x;
     vy1 := tVector1.y - tVector2.y;
     vz1 := tVector1.z - tVector2.z;

     vx2 := tVector2.x - tVector3.x;
     vy2 := tVector2.y - tVector3.y;
     vz2 := tVector2.z - tVector3.z;

     nx := vy1*vz2 - vz1*vy2;
     ny := vz1*vx2 - vx1*vz2;
     nz := vx1*vy2 - vy1*vx2;

     v := SQRT (nx*nx + ny*ny + nz*nz);
     IF v = 0 THEN v := 1; // проверка на нулевую длину

     // Получаем унитарный вектор нормали 
     FNormals[i].x := nx / v;
     FNormals[i].y := ny / v;
     FNormals[i].z := nz / v;
  end;


Получить нормаль к каждой из вершин грани можно, используя нормали к смежным граням, вычисленные по алгоритму, приведенному выше.  smile 


--------------------
...все в мире относительно
PM   Вверх
ZC1989
Дата 4.1.2007, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 468
Регистрация: 17.7.2006
Где: Нижний Новгород; Россия

Репутация: нет
Всего: 1



Nicholas_S, впринцыпе оно и есть, я нашёл у себя статью где это опысывалось...

если кому надо то суть такая: надо суммировать нормали всех плоскостей содержащих эту точку, потом нормализовать все вектора и вуаля, список нормалей индивидуальных для кажой точки! а изначально, перед началом суммирования, надо все нормальные вектора прописать нулевыми  smile   -0 всё гениалное просто!


--------------------
озарение настанет позже, когда поймём больше... (Сo. Stigmata)
PM MAIL ICQ   Вверх
Bitter
Дата 4.1.2007, 23:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный лентяй
***


Профиль
Группа: Завсегдатай
Сообщений: 1209
Регистрация: 15.8.2004
Где: Харьков, Ukraine

Репутация: 5
Всего: 27



ZC1989, именно так! Вот то, что обещал (словесное описание в качестве коментариев):

Код

function CrossProduct(a, b: TVector): TVector;
begin
 Result.x := a.y * b.z - a.z * b.y;
 Result.y := a.z * b.x - a.x * b.z;
 Result.z := a.x * b.y - a.y * b.x;
end;

procedure TForm2.CalcNormals;
var m:Single;
    u,l,k,i,j:integer;
    p,q,d,a,b,c:TVector;
    Normals:array of TVector;
begin
 for i:=1 to Object.SubCount do // Количество подообъектов
 begin

  {сначала расчитываем не сглаженные нормали}

  SetLength(Normals,Object.SubObjects[i-1].FaceCount);  // установить длинну массива Normals = количество граней

  for j:=1 to Object.SubObjects[i-1].FaceCount do
  begin
   a:=Object.SubObjects[i-1].Faces[j-1].Vertexs[1];     // a, b, с - вершины текущей грани
   b:=Object.SubObjects[i-1].Faces[j-1].Vertexs[2];     // 
   c:=Object.SubObjects[i-1].Faces[j-1].Vertexs[3];

   p:=Vector(b.x-a.x,b.y-a.y,b.z-a.z);                  // p, q - вектора (b-a) и (c-a)
   q:=Vector(c.x-a.x,c.y-a.y,c.z-a.z);
   Normals[j-1]:=NormalizeVec(CrossProduct(p,q));       // получаем нормаль к грани (CrossProduct описан выше)
  end;

  {теперь сглаживаем их. смысл в том, чтобы найти совпадающие вершины и просуммировать их нормали}

  for j:=1 to Object.SubObjects[i-1].FaceCount do
   for k:=1 to 3 do // to 3, потому что 3 вершины в каждой грани
   begin
    a:=Object.SubObjects[i-1].Faces[j-1].Vertexs[k]; // выбираем очередную вершину
    b:=Normals[j-1];                                 // b - нормаль к текущей грани

    for l:=1 to Object.SubObjects[i-1].FaceCount do  // в этом цикле будем искать одинаковые вершины
    begin

     if j<>l then                     // если i != j, т.е. рассматриваются разные грани
      for u:=1 to 3 do
      begin
       c:=Object.SubObjects[i-1].Faces[l-1].Vertexs[u];

       if (c.x=a.x)and(c.y=a.y)and(c.z=a.z) then     // если вектор a равен вектору c, т.е. вершины совпадают
       begin
        d:=Normals[l-1];
        m:=ArcCos(DotProduct(b,d))*180/Pi;           // m - угол между двумя нормалями
        if m<Angle then b:=AddVector(b,d);           // если m < заданного угла, добавляем к b вектор d
        Break;                                       // выход из цикла
       end;

      end;
    end;
    Object.SubObjects[i-1].Faces[j-1].Normals[k]:=NormalizeVec(b); // нормализуем и сохраняем полученную нормаль
   end;

 end;
end;



вообще-то реализация зависит от формы организации данных. В данном случае имеется массив граней, каждый элемент которого хранит три вершины, три нормали и три текстурные координаты.

Цитата

объект получается инвертирован слева-на-право


а если камеру разместить с другой стороны, то получится нормальным. или я может чего-то не понял?
PM MAIL ICQ Skype   Вверх
ZC1989
Дата 5.1.2007, 00:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 468
Регистрация: 17.7.2006
Где: Нижний Новгород; Россия

Репутация: нет
Всего: 1



Bitter
Цитата

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

ты не понял... представь, что будет с объектом если все координаты по Х умножить на -1, получится зеркальное отражение

Добавлено @ 00:04 
там ещё объект поворачивался на 90 градусов по Y оси, но я нашёл простое решение, менять у точек координаты Y и Z, и менять местами 1 и третью вершыны, что, как мне кажется геморойно...


--------------------
озарение настанет позже, когда поймём больше... (Сo. Stigmata)
PM MAIL ICQ   Вверх
Страницы: (5) Все 1 2 [3] 4 5 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Программирование игр, графики и искуственного интеллекта"
Rickert

НА ЗЛОБУ ДНЯ: Дорогие посетители, прошу обратить внимание что новые темы касающиеся новых вопросов создаются кнопкой "Новая тема" а не "Ответить"! Любые оффтопиковые вопросы, заданные в текущих тематических темах будут удалены а их авторы, при рецедиве, забанены.

  • Литературу, связанную с программированием графики, обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы связанные с программированием графики и мультимедии на языках С++ и Delphi
  • Вопросы по реализации алгоритмов рассматриваются здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rickert.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Программирование игр, графики и искусственного интеллекта | Следующая тема »


 




[ Время генерации скрипта: 0.1049 ]   [ Использовано запросов: 20 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.