Форум программистов, компьютерный форум, киберфорум
OpenGL
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
 Аватар для GoldenId
142 / 143 / 64
Регистрация: 11.11.2010
Сообщений: 877
Записей в блоге: 10

Неправильно генерируется модель

26.01.2021, 10:39. Показов 1218. Ответов 5

Студворк — интернет-сервис помощи студентам
Пишу & программу & работающую с кубиком Рубика & Генерирую его модель в коде & Она генерируется неправильно & Сам ошибки найти & затрудняюсь.



RubikCube.2021.01.26.zip
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
26.01.2021, 10:39
Ответы с готовыми решениями:

Неправильно экспортируется модель (Maya)
В общем у меня такая проблема: Из текстуры я получаю 3d-модель (на первом рисунке). Во время экспорта модель почему то теряет объемные...

Модель лодочной станции, работает неправильно
Привет, зарегистрировался только чтобы спросить. Это ссылка на программу Проблема в следующем: Это моделирование работы...

Все меши сдвигаются неправильно и модель раскидывает в разные стороны
private void DrawModel(Model m, Vector3 positionModel) { Matrix position = Matrix.CreateTranslation(positionModel); Matrix transforms...

5
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
26.01.2021, 11:41
GoldenId, а можно не проект выкладывать, а фрагмент кода с генерацией куба?

Кубик - это очень просто, например, я так делал:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
    VertexArray cube(GLfloat halfSize)
    {
 /*
 *     7--------6
 *    /|       /|
 *   / |      / |
 *  3--------2  |
 *  |  |     |  |
 *  |  4-----|--5
 *  | /      | /
 *  |/       |/
 *  0--------1
*/
        static const gl::vec3 normals[] = {
            { 0.0f,  0.0f,  1.0f}, // 0, 1, 2, 3 - front
            { 1.0f,  0.0f,  0.0f}, // 1, 5, 6, 2 - right
            { 0.0f,  0.0f, -1.0f}, // 5, 4, 7, 6 - back
            {-1.0f,  0.0f,  0.0f}, // 4, 0, 3, 7 - left
            { 0.0f,  1.0f,  0.0f}, // 3, 2, 6, 7 - top
            { 0.0f, -1.0f,  0.0f}  // 4, 5, 1, 0 - bottom
        };
        static const gl::vec3 positions[] = {
            {-1.0f, -1.0f,  1.0f}, { 1.0f, -1.0f,  1.0f}, { 1.0f,  1.0f,  1.0f}, // 0, 1, 2 - front
            {-1.0f, -1.0f,  1.0f}, { 1.0f,  1.0f,  1.0f}, {-1.0f,  1.0f,  1.0f}, // 0, 2, 3 - front
            { 1.0f, -1.0f,  1.0f}, { 1.0f, -1.0f, -1.0f}, { 1.0f,  1.0f, -1.0f}, // 1, 5, 6 - right
            { 1.0f, -1.0f,  1.0f}, { 1.0f,  1.0f, -1.0f}, { 1.0f,  1.0f,  1.0f}, // 1, 6, 2 - right
            { 1.0f, -1.0f, -1.0f}, {-1.0f, -1.0f, -1.0f}, {-1.0f,  1.0f, -1.0f}, // 5, 4, 7 - back
            { 1.0f, -1.0f, -1.0f}, {-1.0f,  1.0f, -1.0f}, { 1.0f,  1.0f, -1.0f}, // 5, 7, 6 - back
            {-1.0f, -1.0f, -1.0f}, {-1.0f, -1.0f,  1.0f}, {-1.0f,  1.0f,  1.0f}, // 4, 0, 3 - left
            {-1.0f, -1.0f, -1.0f}, {-1.0f,  1.0f,  1.0f}, {-1.0f,  1.0f, -1.0f}, // 4, 3, 7 - left
            {-1.0f,  1.0f,  1.0f}, { 1.0f,  1.0f,  1.0f}, { 1.0f,  1.0f, -1.0f}, // 3, 2, 6 - top
            {-1.0f,  1.0f,  1.0f}, { 1.0f,  1.0f, -1.0f}, {-1.0f,  1.0f, -1.0f}, // 3, 6, 7 - top
            {-1.0f, -1.0f, -1.0f}, { 1.0f, -1.0f, -1.0f}, { 1.0f, -1.0f,  1.0f}, // 4, 5, 1 - bottom
            {-1.0f, -1.0f, -1.0f}, { 1.0f, -1.0f,  1.0f}, {-1.0f, -1.0f,  1.0f}  // 4, 1, 0 - bottom
        };
 
        static const gl::vec2 texCoords[] = {
            {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f},
        };
 
        VertexArray result;
        result.primType = gl::PrimitiveType::Triangles;
        result.vertices.reserve(36);
        for (GLuint posIdx = 0, norIdx = 0, uvIdx = 0; posIdx < 36;)
        {
            result.vertices.emplace_back(Vertex3{positions[posIdx] * halfSize, normals[norIdx], texCoords[uvIdx]});
            ++posIdx;
            uvIdx = (uvIdx + 1) % 6;
            if (posIdx % 6 == 0) ++norIdx;
        }
        return result;
    }
0
 Аватар для GoldenId
142 / 143 / 64
Регистрация: 11.11.2010
Сообщений: 877
Записей в блоге: 10
26.01.2021, 11:54  [ТС]
zayats80888, так:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#ifdef RUBIK_CUBE_PIECES_PLAIN_STORAGE
 
    // сгенерируем квадраты и куски
    
    glm::ivec3 center(0);
    glm::icomp_t lo = -( glm::icomp_t ) ( layerCount / 2 ), hi = -lo;
    bool even = layerCount % 2 == 0;
    // для каджой из 6 сторон
    for (auto iSide = s_aStructure.begin(); iSide != s_aStructure.end(); iSide++)
    {
        // локальные координаты c1, c2
        for (int c1 = lo; c1 <= hi; ++c1)
        {
            if (c1 == 0 && even)
                continue;
 
            for (int c2 = lo; c2 <= hi; ++c2)
            {
                if (c2 == 0 && even)
                    continue;
 
                // todo: optimize
                glm::imat4 mTrans = glm::lookAt( glm::vec3( center ), -glm::vec3( iSide->out ), glm::vec3( iSide->up ) );   // в ту ли сторону:
                _ASSERT_EXPR( layerCount == 3, "Unsupported number of layers of the cube. Watch z in next string." );
                // todo: optimize
                auto pos = M4V3Mult( mTrans, RC_PD( c1, c2, lo ) );
                TQuad quad;
                quad.eColor = iSide->eColor;
                quad.normal = M4V3Mult( mTrans, RC_PD( 0, 0, -1 ) );
 
                auto iPrevPiece = find_if( _aPieces.begin(), _aPieces.end(), [pos] ( auto p ) { return p.pos == pos; } );
                if (iPrevPiece == _aPieces.end())
                {
                    TPiece piece;
                    piece.pos = pos;
                    piece.aQs.push_back(quad);
                    piece.imTrans = glm::imat4(1);
                    _aPieces.push_back(piece);
                }
                else
                {
                    iPrevPiece->aQs.push_back(quad);
                }
            }
        }
    }
 
    // создание и заполнение вершинных буферов
    float k = edgeLength / layerCount;
    float l = edgeLength;
    GLfloat g_vertex_buffer_data[ 3 * /*максимум 3 квадрата*/ 2 * /*по два треугольника*/ 3 * /* по 3 вершины*/ 3/*по 3 координаты*/ ];
    GLfloat g_color_buffer_data[ 3 * /*максимум 3 квадрата*/ 2 * /*по два треугольника*/ 3 * /* по 3 вершины*/ 3/*по 3 координаты*/ ];
    for (auto& p : _aPieces)
    {
        glm::vec3* pV = ( glm::vec3* ) & g_vertex_buffer_data[ 0 ];
        glm::vec3* pC = ( glm::vec3* ) & g_color_buffer_data[ 0 ];
 
        for (auto& q : p.aQs)
        {
 
            glm::ivec3 front = glm::ivec3(q.normal);
            auto iSide = std::find_if(s_aStructure.begin(), s_aStructure.end(), [front](const TSide& side) { return side.out == front; });
            _ASSERT_EXPR(iSide != s_aStructure.end(), "Corrupted Rubik's cube generation data");
            glm::ivec3 up = iSide->up;
            glm::mat4 mTrans = lookAt( glm::vec3( center ), glm::vec3( front ), glm::vec3( up ) );
 
            _ASSERT_EXPR( !even, "Unsupported number of layers of the cube." );
            //if ( !( ( iSide->eColor == ec_0 ) || ( iSide->eColor == ec_1 ) || ( iSide->eColor == ec_2 ) ) )
            //  continue;
 
            *pV = glm::vec3( ( glm::vec4( glm::ivec4( p.pos, 0 ) ) * k + mTrans * glm::vec4(  k,  k, -l, 0.0f ) ) * 0.5f );
            pV++;
            *pV = glm::vec3( ( glm::vec4( glm::ivec4( p.pos, 0 ) ) * k + mTrans * glm::vec4( -k,  k, -l, 0.0f ) ) * 0.5f );
            pV++;
            *pV = glm::vec3( ( glm::vec4( glm::ivec4( p.pos, 0 ) ) * k + mTrans * glm::vec4( -k, -k, -l, 0.0f ) ) * 0.5f );
            pV++;
            *pV = glm::vec3( ( glm::vec4( glm::ivec4( p.pos, 0 ) ) * k + mTrans * glm::vec4(  k,  k, -l, 0.0f ) ) * 0.5f );
            pV++;
            *pV = glm::vec3( ( glm::vec4( glm::ivec4( p.pos, 0 ) ) * k + mTrans * glm::vec4( -k, -k, -l, 0.0f ) ) * 0.5f );
            pV++;
            *pV = glm::vec3( ( glm::vec4( glm::ivec4( p.pos, 0 ) ) * k + mTrans * glm::vec4(  k, -k, -l, 0.0f ) ) * 0.5f );
            pV++;
 
            for (int v = 0; v < 6; v++, pC++)
                *pC = iSide->color;
        }
        glGenBuffers(1, &p.vertexBuffer);
        glBindBuffer(GL_ARRAY_BUFFER, p.vertexBuffer);
        glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * 3 * 2 * p.aQs.size(), g_vertex_buffer_data, GL_STATIC_DRAW);
 
        glGenBuffers(1, &p.colorBuffer);
        glBindBuffer(GL_ARRAY_BUFFER, p.colorBuffer);
        glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * 3 * 2 * p.aQs.size(), g_color_buffer_data, GL_STATIC_DRAW);
    }
#endif

достаточно?
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
26.01.2021, 13:02
Цитата Сообщение от GoldenId Посмотреть сообщение
достаточно?
Я надеюсь это не троллинг...
Если вы хотите помощи, то потрудитесь объяснить, что именно вы делаете в этом коде.
Что из себя представляют исходные данные для генерации.
Что именно вы генерируете.
Опишите выбранный вами алгоритм в общих чертах.
Я надеюсь вы не думаете, что кто-то будет разбираться в том, что вы накодили без этой информации. На это нужно время и терпение.
В конце концов это вам помощь нужна.

Добавлено через 1 минуту
Цитата Сообщение от GoldenId Посмотреть сообщение
glm::icomp_t
А это что такое? В glm такого нет по моему.

Добавлено через 9 минут
Цитата Сообщение от GoldenId Посмотреть сообщение
glm::imat4 mTrans = glm::lookAt( glm::vec3( center ), -glm::vec3( iSide->out ), glm::vec3( iSide->up ) );   // в ту ли сторону:
Не вникая в детали, сходу могу сказать, что использовать lookAt матрицу в качестве матрицы модели не правильно, т. к. это матрица обратного преобразования.
0
 Аватар для GoldenId
142 / 143 / 64
Регистрация: 11.11.2010
Сообщений: 877
Записей в блоге: 10
26.01.2021, 13:35  [ТС]

Не по теме:

Цитата Сообщение от zayats80888 Посмотреть сообщение
Я надеюсь это не троллинг...
Я надеюсь, это:
Цитата Сообщение от zayats80888 Посмотреть сообщение
Кубик - это очень просто
тоже.



Я храню квадраты (наклейки) в кусках в кубике:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class CRubikCube
{
public:
    struct TPiece
    {
        // часть данных, нужная для работы алгоритма
        position_direction_t    pos;            // исходное положение куска в собранном к.Р.
        std::vector<TQuad>      aQs;            // квадраты куска
        glm::imat4              imTrans;        // матрица, отвечающая за перевод из позиции куска в собранном к.Р. в текущую позицию в мировых координатах
 
        /* ... */
    };
 
private:
    std::vector<TPiece>     _aPieces;
    /* ... */
};
Есть структура, описывающая стороны кубика:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
const std::vector<CRubikCube::TSide> CRubikCube::s_aStructure
{
    { CRubikCube::EColor::ec_0, /* верхняя               - белая */     { 1.000f, 1.000f, 1.000f }, {  0,  1,  0 }, { 0, 0, -1 } },
    { CRubikCube::EColor::ec_1, /* первая боковая      - красная */ { 1.000f, 0.000f, 0.000f }, {  0,  0,  1 }, { 0, 1,  0 } },
    { CRubikCube::EColor::ec_2, /* вторая боковая      - синяя */     { 0.000f, 0.000f, 1.000f }, {  1,  0,  0 }, { 0, 1,  0 } },
    { CRubikCube::EColor::ec_3, /* третья боковая      - оранжевая */ { 1.000f, 0.500f, 0.000f }, {  0,  0, -1 }, { 0, 1,  0 } },
    { CRubikCube::EColor::ec_4, /* четвёртая боковая    - зелёная */ { 0.000f, 1.000f, 0.000f }, { -1,  0,  0 }, { 0, 1,  0 } },
    { CRubikCube::EColor::ec_5, /* нижняя             - жёлтая */       { 1.000f, 1.000f, 0.000f }, {  0, -1,  0 }, { 0, 0,  1 } }
};
C++
1
2
3
4
5
6
7
    struct TSide
    {
        EColor eColor;
        glm::vec3 color;
        glm::ivec3 out; //внешняя нормаль к стороне
        glm::ivec3 up; // верх стороны, для некоторых вызовов
    };


В первом цикле, начинающемся на строке 9, я прохожу по всем сторонам и генерирую куски и квадраты (наклейки) по целочисленному положению, если раньше с таким положением - не было. Циклы в строках 12 и 17 - проход по квадратам стороны.

Во втором цикле, начинающемся на строке 53, я прохожу по всем кускам и по их квадратам (строка 58) и создаю вершинные буферы (данные для которых в строках 51, 52), которые заполняю в строках 71-85. Похоже, ошибки где-то в строках 71-82 (как-то не так генерируются координаты). Идея была в том, чтобы создать в них квадрат из двух треугольников, из 6 вершин. В строке 65 я делаю матрицу поворота от фронтального положения квадрата к положению в стороне, может быть, одна из ошибок - здесь.

Строки 87-93 - генерирование и заполнение буферов положения и цвета.

Кроме того есть ощущение, что что-то вроде того, что в каждой следующей стороне генерируется меньше треугольников, чем в предыдущей. Или отображается. Жёлтая, последняя сторона не отображается вообще, в зелёной, предпоследней отображается один треугольник, белая - первая - отображается полностью. Если изменять код так, чтобы генерировалась, например, только жёлтая, последняя сторона, то она будет отображаться полностью.

Добавлено через 4 минуты
Цитата Сообщение от zayats80888 Посмотреть сообщение
glm::icomp_t
я определил:
C++
1
2
3
4
5
6
namespace glm
{
    // тип целочисленного компонента
    typedef int                         icomp_t;
    /* ... */
}
для
C++
1
2
3
4
5
6
7
8
9
10
11
12
namespace glm
{
    // целочисленный вектор 3
    typedef tvec3<icomp_t, defaultp>    ivec3;
 
    // целочисленный вектор 4
    typedef tvec4<icomp_t, defaultp>    ivec4;
 
    // целочисленная матрица 4 на 4 для ориентации относительно кубика Рубика при сборке
    typedef tmat4x4<icomp_t, defaultp>  imat4;
    /* ... */
}
Добавлено через 5 минут
Цитата Сообщение от zayats80888 Посмотреть сообщение
glm::imat4 mTrans = glm::lookAt( glm::vec3( center ), -glm::vec3( iSide->out ), glm::vec3( iSide->up ) );   // в ту ли сторону:
Не вникая в детали, сходу могу сказать, что использовать lookAt матрицу в качестве матрицы модели не правильно, т. к. это матрица обратного преобразования.
Я использую её для преобразования из фронтального положения в положение в стороне (поворот из фронтального положения в положение в стороне), очень удобно задать просто по внешней нормали (и верху).
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
26.01.2021, 16:18
GoldenId, вы как то усложнили всё.
Ваша основная ошибка в отрисовке:
C++
1
2
    glDrawArrays( GL_TRIANGLES, 0, piece.aQs.size() * 6 ); // triangles
    //                                                ^ !!!!!!!!!!
Вторая ошибка - вы используете матрицу lookAt для трансформации вершин, просто постройте матрицу модели:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//...
            glm::ivec3 front = glm::ivec3(q.normal);
            auto iSide = std::find_if(s_aStructure.begin(), s_aStructure.end(), [front](const TSide& side) { return side.out == front; });
            _ASSERT_EXPR(iSide != s_aStructure.end(), "Corrupted Rubik's cube generation data");
            glm::vec3 up = iSide->up;
            glm::mat4 mTrans;
            mTrans[0] = glm::vec4(normalize(cross(up, glm::vec3(-front))), 0.0f);
            mTrans[1] = glm::vec4(up, 0.0f);
            mTrans[2] = glm::vec4(-front, 0.0f);
            mTrans[3] = glm::vec4(glm::vec3(p.pos) * k, 1.0f);
 
            _ASSERT_EXPR( !even, "Unsupported number of layers of the cube." );
            //if ( !( ( iSide->eColor == ec_0 ) || ( iSide->eColor == ec_1 ) || ( iSide->eColor == ec_2 ) ) )
            //  continue;
 
            const float c = k * 0.5f;
            *pV = glm::vec3( mTrans * glm::vec4( c,  c, -c, 1.0f ) );
            pV++;
            *pV = glm::vec3( mTrans * glm::vec4(-c,  c, -c, 1.0f ) );
            pV++;
            *pV = glm::vec3( mTrans * glm::vec4(-c, -c, -c, 1.0f ) );
            pV++;
            *pV = glm::vec3( mTrans * glm::vec4( c,  c, -c, 1.0f ) );
            pV++;
            *pV = glm::vec3( mTrans * glm::vec4(-c, -c, -c, 1.0f ) );
            pV++;
            *pV = glm::vec3( mTrans * glm::vec4( c, -c, -c, 1.0f ) );
            pV++;
 
//...

Не по теме:

И вообще в коде полно UB, включая этот каст буферов и запись туда векторов. Поставьте 4 уровень предупреждений (/W4).

1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
26.01.2021, 16:18
Помогаю со студенческими работами здесь

Не генерируется бд из модели
Добрый день, помогите пожалуйста, как решить данную проблему? (БД SQLite)

Не генерируется круг
Доброго времени суток, не понимаю, почему не генерируеться круг? Начал только меш изучать, так и не понял почему не работает, хотя сферы...

Не генерируется прокси
Всем привет, у меня такая проблема: есть служба и ее используют два приложения WinForms. Пытаюсь добавить на нее ссылку, в результате в...

Не генерируется R.java
Всем привет! Не знаю, можно ли писать просто сообщение, но попробую. История такова: после нескольких манипуляций с проектом -...

Проверьте задачку по циклам, неправильно работает. [думаю что неправильно]
Спасибо что решили зайти. Задание выгладит так: http://*******/PW95p А результат выплнения: http://*******/KwhuS #include...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Модель заражения группы наркоманов
alhaos 17.04.2026
Условия задачи сформулированы тут Суть: - Группа наркоманов из 10 человек. - Только один инфицирован ВИЧ. - Колются одной иглой. - Колются раз в день. - Колются последовательно через. . .
Мысли в слух. Про "навсегда".
kumehtar 16.04.2026
Подумалось тут, что наверное очень глупо использовать во всяких своих установках понятие "навсегда". Это очень сильное понятие, и я только начинаю понимать край его смысла, не смотря на то что давно. . .
My Business CRM
MaGz GoLd 16.04.2026
Всем привет, недавно возникла потребность создать CRM, для личных нужд. Собственно программа предоставляет из себя базу данных клиентов, в которой можно фиксировать звонки, стадии сделки, а также. . .
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru