Esate.ru

Вычисление текстурных координат

Доброго времени суток.
Возникла потребность в создании генератора текстурных координат. Предположим, существует набор вершин произвольного трёхмерного объекта, сложной формы. Так при загрузке или создании подобного объекта, а быть может прямо во время его отрисовки, было бы здорово рассчитать текстурные координаты. Основной проблемой является определение коэффициента масштабирования.


У меня есть некоторые идеи на это счёт:
/*http://esate.ru, GLarus*/


      /// <summary>
      /// Вычисление текстурных координат полигона
      /// </summary>
      /// <param name="v1"> мировые координаты вершин треугольной грани,   </param>
      /// <param name="v2"> перечисленные в порядке </param>
      /// <param name="v3"> против часовой стрелки </param>
      /// <param name="scaleCoeff"> коэффициент масштабирования </param>
      /// <param name="t1"> текстурные </param>
      /// <param name="t2"> координаты </param>
      /// <param name="t3"> грани</param>
      public static void CalculatePolygonTextureCoordinates(
        Vector v1, Vector v2, Vector v3,
        float scaleCoeff,
        out Vector t1, out Vector t2, out Vector t3)
      {

        //Вычисляем нормаль треугольника:
        Vector n = Vector.NormalVector(v1, v2, v3);
        n = Vector.NormalizeVector(n);

        //Матрица масштабирования
        //|1|0|0|
        //|0|1|0|
        //|0|0|1|
        Matrix3 scale = new Matrix3();
        //-------------------------------------------------------------------------------------
        //Вычислим углы между плоскостью полигона и плоскостями XY,XZ,YZ
        //-------------------------------------------------------------------------------------

        float angX = (float)Vector.CalculateAngle(n, new Vector(1, 0, 0));
        float angY = (float)Vector.CalculateAngle(n, new Vector(0, 1, 0));
        float angZ = (float)Vector.CalculateAngle(n, new Vector(0, 0, 1));

        //Вычисляем матрицу поворота
        Matrix3 rotate = Matrix3.CreateRotateMatrix(angX, angY, angZ);

        //Инициализируем масштабирующую матрицу
        scale.R[0, 0] = scaleCoeff;
        scale.R[1, 1] = scaleCoeff;
        scale.R[2, 2] = scaleCoeff;  

        //-------------------------------------------------------------------------------------
        //Вычисляем ТК:
        //-------------------------------------------------------------------------------------
        Vector vt; //Трансформированная вершина
        vt = Matrix3.Transform(rotate, v1);
        vt = Matrix3.Transform(scale, vt);
        t1 = new Vector(vt.x, vt.y, 0);

        vt = Matrix3.Transform(rotate, v2);
        vt = Matrix3.Transform(scale, vt);
        t2 = new Vector(vt.x, vt.y, 0);

        vt = Matrix3.Transform(rotate, v3);
        vt = Matrix3.Transform(scale, vt);
        t3 = new Vector(vt.x, vt.y, 0);



Собственно причём тут координаты вершин. Так вот, предположим, что текстурные координаты - это особенным образом трансформированные мировые координаты вершин. И чтобы связать их с мировыми координатами, я сначала связываю их с локальными координатами объекта, а потом, используя афинные преобразования, привожу тк к мировым.

Пример объекта, масштабированного после поворота, с текстурой наложенной приведённым способом, но без масштабирующего коэффициента:


Рисуем:
/*http://esate.ru, GLarus*/


for (int i = 0; i < listBarriers.Count; i++)
{
Gl.glBindTexture(Gl.GL_TEXTURE_2D, listBarriers[i].cover[0].texObj);
Gl.glBegin(Gl.GL_TRIANGLES);
for (int j = 0; j < listBarriers[i].facesCount; j++)
                {
float x1, x2, x3, y1, y2, y3, z1, z2, z3;
                   // вытакскиваем координаты треугольника (полигона)
                   x1 = listBarriers[i].vertex[0, listBarriers[i].faces[0, j]];
                   x2 = listBarriers[i].vertex[0, listBarriers[i].faces[1, j]];
                   x3 = listBarriers[i].vertex[0, listBarriers[i].faces[2, j]];
                   y1 = listBarriers[i].vertex[1, listBarriers[i].faces[0, j]];
                   y2 = listBarriers[i].vertex[1, listBarriers[i].faces[1, j]];
                   y3 = listBarriers[i].vertex[1, listBarriers[i].faces[2, j]];
                   z1 = listBarriers[i].vertex[2, listBarriers[i].faces[0, j]];
                   z2 = listBarriers[i].vertex[2, listBarriers[i].faces[1, j]];
                   z3 = listBarriers[i].vertex[2, listBarriers[i].faces[2, j]];

                      Vector v1 = new Vector(x1, y1, z1);
                      Vector v2 = new Vector(x2, y2, z2);
                      Vector v3 = new Vector(x3, y3, z3);

TextureScaling.CalculatePolygonTextureCoordinates(
                        v1,
                        v2,
                        v3,
                        scaleCoeff,//Как рассчитать?
                        out t1, out t2, out t3);

                        Gl.glTexCoord2f(t1.x, t1.y);
                        Gl.glVertex3f(x1, y1, z1);
 
                        Gl.glTexCoord2f(t2.x, t2.y);
                        Gl.glVertex3f(x2, y2, z2);

                        Gl.glTexCoord2f(t3.x, t3.y);
                        Gl.glVertex3f(x3, y3, z3);

}
Gl.glEnd();
}


Есть ли какой - нибудь алгоритм вычисления масштабирующего коэффициента?
И быть может кто-нибудь пыталсь реализовать или реализовал эту задачу?

Буду благодарен за внимание.

</cut>

0       2520        11.03.2011        13
0  
11.03.2011 00:00:00
В opengl можно не мучатся с матрицами, просто сделай текущей матрицу текстурирования и применяй к текстурам glScaled glRotated итд
Ссылка 0  
0  
12.03.2011 00:00:00
Например так, да:

Gl.glMatrixMode(Gl.GL_TEXTURE);
Gl.glLoadIdentity();
Gl.glScalef(0.5f, 0.5f, 0.5f);
Gl.glMatrixMode(Gl.GL_MODELVIEW);

Но опять тот же вопрос, как вычислить параметры для glScalef(d)? Они не соответствуют параметрам, которые я применяю для масштабирования самого объекта.
Родитель Ссылка 0  
0  
12.03.2011 00:00:00
Ты хочешь, что бы при изменении размера объекта, изменялся размер текстуры? Можно в матрице modelview привязать текстурные координаты к объекту и при изменении его размера, текстура сама должна изменять изменять размер.

glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);

Возможно, я не так понял вопрос…
Родитель Ссылка 0  
0  
12.03.2011 00:00:00
К сожалению всё не так просто, попробую объяснить как следует к чему я стремлюсь. Программа, которую я делаю включает в себя что-то вроде редактора. Мне захотелось собственноручно написать генератор текстурных координат. Потому что создав сложную поверхность или загрузив модель, имея только вершины, нужно привязать к объектам текстуры. Я знаю о встроенной gl функции для генерации тк, да и модель можно загрузить уже с тк, поэтому сейчас меня интересует только одна вещь, которая, если я правильно разобрался, необходима в любом случае. Это сохранение пропорций текстуры. Я хочу, чтобы кирпичики на текстуре всегда были одного размера на всех гранях не зависимо от их размера, ориентации.
Например для параллепипеда очень просто можно сохранять пропорции текстуры — домножить текстурные координаты на половину длины данной грани. Но это не работает в том случае, который на скриншоте(1), когда после поворота, осуществляется масштабирование объекта. Вопрос как сохранить пропорции текстуры для объекта? Как добиться того, чтобы например на цилиндре всегда были кирпичи одинакового размера?


Родитель Ссылка 0  
0  
12.03.2011 00:00:00
я в текстурированнии не очень сильно понимаю, не хотел вникать в это из за ненадобности, но попробуй узнать отношение от первоначального размера до полученого и умножить это на соответствующую ось на координатах, по идее она трансфармируется с таким же отнашением и получится корректное изображение

простите за ошибки))
Родитель Ссылка 0  
0  
12.03.2011 00:00:00
Спасибо) Думал о чём-то подобном. Получается, что нужно хранить информацию о каждом полигоне до и после масштабирования объекта, либо хранить только отношение размеров, а потом учитывать при наложении текстуры?
Родитель Ссылка 0  
0  
13.03.2011 00:00:00
попробуй так и так
я вобще не знаю получится ли, хотя вроде должно
эт я так прочитал и сразу такой вот выход придумал
Родитель Ссылка 0  
0  
13.03.2011 00:00:00
А что, если привязать текстуру только к верхним вершинам? Я не пробовал, но по идеи, она не должна сплющиться. Так же можно попробовать вообще не создавать текстурных координат.

Или вот ещё идея пришла: Когда ты scale делаешь, то всё происходит в modelviev, а если после этого открыть матрицу текстуры и изменить scale на предыдущий размер? Но это бредово, но можно попробовать…
Ссылка 0  
0  
13.03.2011 00:00:00
Но одно я предполагаю точно, что масштабы тут не нужны, нужно генерировать текстурные координаты. Или в конце концов перейти к кубической карте.
Родитель Ссылка 0  
0  
13.03.2011 00:00:00
масштабы как раз токи нада
как ты узнаешь как у тебя изменился полигон?? вот ты его отскалил а получится что текстурка такаяя же осталось

кстати я тут подумал, не надо хранить скал каждого полигона
ы что их менять будешь?? или всю модель??
Родитель Ссылка 0  
0  
13.03.2011 00:00:00
Мне надо сконструировать помещение, а потом делать кое-какие расчёты. Т.е. надобно постоянно трансформировать объекты в процессе планировки.
Родитель Ссылка 0  
0  
14.03.2011 00:00:00
делай так:

если трансформируешь модель то как я писал выше, если полигон то считай уже только относительно полигона, хотя я думаю что это не надо так как там должно быть и так нормально
Родитель Ссылка 0  
0  
29.04.2011 00:00:00
Пожалуй, стоит однозначно завершить тему, обозначив результат. В итоге я делал так:
для всех объектов сохранял масштабирующие коэффициенты, которые я просто накапливал в процессе трансформации, а затем

Gl.glMatrixMode(Gl.GL_TEXTURE);
Gl.glLoadIdentity();
Gl.glScalef(object.scaleX, object.scaleY, object.scaleZ);
Gl.glMatrixMode(Gl.GL_MODELVIEW);

(Как мне предлагал amid в 1 комментарие)
Плюс использовал бесшовные текстуры, хорошего разрешения. Сделал их покрупнее, поделив текстурные координаты на некоторую величину.
Мне этого оказалось вполне достаточно для приличного отображения объектов на сцене))
Ссылка 0  

Блоги Esate.ru

Регистрация

Регистрируясь, вы принимаете правила сайта. Если вы не получили код подтв. регистрации - не забудьте проверить папку спам.
Логин*
Email*
Пароль*
Подтверждение пароля*
 
Логин*
Код*
 

Восстановление пароля

Пожалуйста, заполните поля, после чего вы получите код подтверждения на ваш E-mail. Если код не пришел в течении нескольких минут - проверьте папку спам.
Логин

или Email
 
Логин*
Код подтверждения*
Новый пароль*
Подтверждение пароля*
 

Авторизация

Пожалуйста, авторизуйтесь, для входа на сайт с помощью соц. сети:
  • Используйте вашу учетную запись на Facebook.com для входа на сайт.
  • Используйте вашу учетную запись VKontakte для входа на сайт.
  • Используйте вашу учетную запись Google для входа на сайт.

или с помощью аккаунта на сайте:

Логин
Пароль