Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Opengl скелетная анимация

69K
06 сентября 2011 года
serpoverst
8 / / 30.06.2011
И снова здравствуйте xD.

Делаю загрузчик 3D с анимацией из 3ds max. Пример взял от сюда"Экспорт анимированных 3D моделей". Взял исходник из примера к статье. Попытался перевести с паскаля на C++.
То что получилось видно на видио. Слева мой вариант.
Мне кажется что мой вариант не такой хароший как тот что справа =).

[video=youtube;hklLuMXwKK8]http://www.youtube.com/watch?v=hklLuMXwKK8[/video]

Так вот собственно вопрос:
Почему у меня нет девушки? xD
И может я не правильно перевел исходник?

Цитата:
main.cpp


Код:
class TModel {
private:
    int Texture;
    int FPS;
    int K_Count;
    int B_Count;
    int V_Count;
    int F_Count;
    int T_Count;
    TVector *Vertex;
    TFace *Face;
    TVector2D *TexCoord;
    TFace *TexFace;
    TWeight **Weight; // веса вершин
    int *int_weight;
    TVector *RVertex; // вершины после применения костей
    TBone *Bone; // список костей и их анимации
    int bon;

public:
    TModel() {
        bon = 1;
    };
    void Load(char *_N);
    void Render(void);
};

void TModel::Load(char *_N) {
    FILE *l_file;
    int i;
    int W_Count;

    char name[50];
    sprintf(name, "%s.mx3", _N);

    if ((l_file = fopen(name, "rb")) == NULL)
        return;
    fread(&K_Count, sizeof(K_Count), 1, l_file);
    fread(&FPS, sizeof(FPS), 1, l_file);
    fread(&B_Count, sizeof(B_Count), 1, l_file);
    fread(&V_Count, sizeof(V_Count), 1, l_file);
    fread(&F_Count, sizeof(F_Count), 1, l_file);
    fread(&T_Count, sizeof(T_Count), 1, l_file);

    Vertex = new TVector[V_Count];
    Face = new TFace[F_Count];
    TexCoord = new TVector2D[T_Count];
    TexFace = new TFace[F_Count];

    // TVector
    fread(Vertex, sizeof(TVector), V_Count, l_file);
    fread(Face, sizeof(TFace), F_Count, l_file);
    fread(TexCoord, sizeof(TVector2D), T_Count, l_file);
    fread(TexFace, sizeof(TFace), F_Count, l_file);

    Weight = (TWeight * *)new int[V_Count];
    int_weight = new int[V_Count];
    for (int i = 0; i < V_Count; i++) {
        fread(&W_Count, sizeof(W_Count), 1, l_file);
        Weight = (TWeight*)malloc(V_Count*sizeof(TWeight));
        fread((void*)Weight, sizeof(TWeight), W_Count, l_file);
        int_weight = W_Count;
    }

    Bone = new TBone[B_Count];
    for (int i = 0; i < B_Count; i++) {
        Bone.Frame = (_TFrame*)malloc(K_Count*sizeof(_TFrame));
        fread(Bone.Frame, sizeof(_TFrame), K_Count, l_file);
    }

    fclose(l_file);
    RVertex = (TVector*)malloc(V_Count*sizeof(TVector));
    sprintf(name, "%s.bmp", _N);
    LoadBitmap(num, name);
    CreateTexture(num, name);
}

void TModel::Render(void) {
    bon += 1;
    if (bon >= K_Count - 1) {
        bon = 1;
    }

    // TVector null_vec=TVector(0,0,0);

    int i, j;
    int lf, nf;
    char dt, t;
    TVector p;
    TQuat r;
    TMatrix W_Matrix;
    /*
    #define _frac(num,i) (i)*((num)/(i) - floor((num)/(i)))
    dt = 1000 / FPS;                       // длительность одного кадра
    lf = (int)floor ((bon/dt)) % K_Count; // вычисляем предыдущий кадр
    nf = (lf + 1) % K_Count;               // и следующий
    t  = _frac(bon,dt);              // временной коэффициент */


    dt = 1; // длительность одного кадра
    lf = bon - 1; // вычисляем предыдущий кадр
    nf = bon + 1; // и следующий
    t = 1;

    // расчёт интерполированных матриц костей

    for (int i = 0; i < B_Count; i++) {
        // линейная интерполяция кватерниона и позиции
        r = Q_Lerp(&Bone.Frame[lf].Rot, &Bone.Frame[nf].Rot, t);
        p = V_Lerp(&Bone.Frame[lf].Pos, &Bone.Frame[nf].Pos, t);


        // расчёт матрицы трансформации для объекта
        Q_Matrix(&r, &Bone.Matrix); // перевод кватерниона в матрицу
        Bone.Matrix[3][0] = p.x; // дописываем позицию в последнюю строку
        Bone.Matrix[3][1] = p.y;
        Bone.Matrix[3][2] = p.z;

    }

    // Расчёт положения вершин в соответствии с текущим состоянием костей
    for (int i = 0; i < V_Count; i++) {
        RVertex = TVector(0, 0, 0);
        for (int j = 0; j < int_weight; j++) {
            // Weight[j]
            M_Mult(&W_Matrix, &Bone[Weight[j].ID].Matrix,Weight[j].Value); // Получение "взвешенной" матрицы
            V_Add(&RVertex, &M_Mult(W_Matrix, &Vertex));
        }
    }

    glBegin(GL_TRIANGLES);
    for (int i = 0; i < F_Count; i++) {
        glTexCoord2f(TexCoord[Face[0]].u, TexCoord[Face[0]].v);
        glVertex3f(RVertex[Face[0]].x, RVertex[Face[0]].y,
            RVertex[Face[0]].z);

        glTexCoord2f(TexCoord[Face[1]].u, TexCoord[Face[1]].v);
        glVertex3f(RVertex[Face[1]].x, RVertex[Face[1]].y,
            RVertex[Face[1]].z);

        glTexCoord2f(TexCoord[Face[2]].u, TexCoord[Face[2]].v);
        glVertex3f(RVertex[Face[2]].x, RVertex[Face[2]].y,
            RVertex[Face[2]].z);
    }
    glEnd();
}


Цитата:
IncludLib.h


Код:
typedef float TMatrix[4][4];
    typedef int TFace[3];
    struct TVector2D{
        float u, v;
    };
    struct TVector{
        TVector(){};
        inline TVector(float _x,float _y,float _z):x(_x),y(_y),z(_z){};
        float x,y,z;
    };
    struct TQuat{
        TQuat() {};
        inline TQuat(float _x,float _y,float _z,float _w):x(_x),y(_y),z(_z),w(_w){}
        float x, y, z, w;   // :Single
    };
    struct _TFrame{
        TVector Pos;  // позиция
        TQuat Rot;    // поворот
    };
    // Вес вершины
    struct TWeight{
        int ID; // Номер кости
        float Value;  // Значение
    };
    // Кость
    struct TBone{
        TMatrix Matrix;
        _TFrame *Frame;
    };

inline TVector M_Mult(TMatrix m,TVector v){
    TVector( m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z + m[3][0],
                m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z + m[3][1],
                    m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z + m[3][2]);
}
inline void M_MultAdd(TVector *result, TMatrix &m, TVector *v){
    result->x += (m[0][0] * v->x + m[1][0] * v->y + m[2][0] * v->z + m[3][0]);
    result->y += (m[0][1] * v->x + m[1][1] * v->y + m[2][1] * v->z + m[3][1]);
    result->z += (m[0][2] * v->x + m[1][2] * v->y + m[2][2] * v->z + m[3][2]);
}
inline M_Mult(TMatrix &result, TMatrix &m, float x){
  for(int i=0; i<4; i++)
    for(int j=0; j<4; j++)
      result[j] = m[j] * x;
};

inline V_Add(TVector *v1,TVector *v2){
    v1->x += v2->x;
    v1->y += v2->y;
    v1->z += v2->z;
}


inline TVector V_Lerp(TVector *v1, TVector *v2 ,float  t){
    return TVector(v1->x + (v2->x - v1->x) * t,v1->y + (v2->y - v1->y) * t,v1->z + (v2->z - v1->z) * t);
};

inline void Q_Matrix(TQuat *q,TMatrix &m){
    float wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;
    x2 =q->x+ q->x;   y2 =q->y+ q->y;   z2 =q->z+ q->z;
    xx =q->x * x2;  xy =q->x * y2;  xz =q->x * z2;
    yy =q->y * y2;  yz =q->y * z2;  zz =q->z * z2;
    wx =q->w * x2;  wy =q->w * y2;  wz =q->w * z2;

    m[0][0] = 1 - (yy + zz);  m[1][0] = xy + wz;        m[2][0] = xz - wy;
    m[0][1] = xy - wz;        m[1][1] = 1 - (xx + zz);  m[2][1] = yz + wx;
    m[0][2] = xz + wy;        m[1][2] = yz - wx;        m[2][2] = 1 - (xx + yy);

    m[3][0] = 0;
    m[3][1] = 0;
    m[3][2] = 0;
    m[0][3] = 0;
    m[1][3] = 0;
    m[2][3] = 0;
    m[3][3] = 1;
}

inline TQuat Q_Add(TQuat *q1,TQuat *q2){
    return TQuat(q1->x + q2->x,q1->y + q2->y,q1->z + q2->z,q1->w + q2->w);
}

inline TQuat Q_Sub(TQuat *q1,TQuat *q2){
    return TQuat(q1->x - q2->x,q1->y - q2->y,q1->z - q2->z,q1->w - q2->w);
}

inline float Q_Dot(TQuat *q1,TQuat *q2){
  return q1->x * q2->x + q1->y * q2->y + q1->z * q2->z + q1->w * q2->w;
}

inline TQuat Q_Mult(TQuat *q,float d){
    return TQuat(q->x * d,q->y * d,q->z * d,q->w * d);
}

inline TQuat Q_Lerp(TQuat *q1,TQuat *q2, float t)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог