1
\$\begingroup\$

[enter image description here][[1]]2

there's problem calculating tangent space and look.... it seems there is no problem with UV code and my shader is 100% no problem. I just copy and pasted tutorial code which works well..

I loaded fbx file and exported to obj file which uses only trianglelists and I parsed it my own OBJparser after parsing I optimize it. find out same vertices and remove it and make index list. here my code

#pragma once
#include"stdafx.h"
#include "ObjLoader.h"
#include <iostream>
// 2017 정윤성

ObjLoader::ObjLoader(char* path, bool istriangle)
{
    file.open(path);
    m_triangle = istriangle;
}

ObjLoader::ObjLoader()
{
}


ObjLoader::~ObjLoader()
{
    file.close();
}

void ObjLoader::openFile(char * path, bool istriangle)
{
    file.open(path);
    m_triangle = istriangle;
}

void ObjLoader::closeFile()
{
    file.close();
    m_vt.clear();
    m_vn.clear();
    m_uv.clear();
    m_idx.clear();
    m_vertice.clear();
    m_indice.clear();
    m_refinedVertice.clear();
}

void ObjLoader::parseOBJ()
{

    XYZ point;
    UV uv;
    int index = 0;
    string line;
    string token;
    char buff;
    char str[256];
    while (!file.eof())
    {
        file.get(buff);
        switch (buff)
        {
        case 'v':
            file.get(buff);
            switch (buff)
            {
            case ' ':
                file >> point.x >> point.y >> point.z;
                point.z = -point.z;
                m_vt.push_back(point);
                break;
            case 't':
                file >> uv.u >> uv.v;
                uv.v = 1.0f - uv.v;
                m_uv.push_back(uv);
                break;
            case 'n':
                file >> point.x >> point.y >> point.z;
                point.z = -point.z;
                m_vn.push_back(point);
                break;
            }
            break;
        case 'f':
            file.get(buff);
            if (m_triangle)
            {
                if (buff == ' ')
                {
                    //f v/vt/vn v/vt/vn v/vt/vn v/vt/vn

                    faceindex index;
                    file.getline(str, sizeof(str));
                    line = str;
                    int idx = 0;
                    faceindex temp[3];
                    for (int i = 0; i < 3; i++)
                    {
                        idx = line.find(' ');
                        token = line.substr(0, idx);
                        sscanf(token.c_str(), "%d/%d/%d", &index.idxV, &index.idxVt, &index.idxVn);
                        index.idxV--;
                        index.idxVn--;
                        index.idxVt--;
                        temp[i] = index;
                        line.erase(0, idx + 1);
                    }
                    m_idx.push_back(temp[0]);
                    m_idx.push_back(temp[2]);
                    m_idx.push_back(temp[1]);
                }
            }
            else
            {
                if (buff == ' ')
                {
                    //f v/vt/vn v/vt/vn v/vt/vn v/vt/vn

                    faceindex index;
                    file.getline(str, sizeof(str));
                    line = str;
                    int idx = 0;
                    faceindex temp[4];
                    for (int i = 0; i < 4; i++)
                    {
                        idx = line.find(' ');
                        token = line.substr(0, idx);
                        sscanf(token.c_str(), "%d/%d/%d", &index.idxV, &index.idxVt, &index.idxVn);
                        index.idxV--;
                        index.idxVn--;
                        index.idxVt--;
                        temp[i] = index;
                        line.erase(0, idx + 1);
                    }
                    m_idx.push_back(temp[0]);
                    m_idx.push_back(temp[2]);
                    m_idx.push_back(temp[1]);


                    m_idx.push_back(temp[0]);
                    m_idx.push_back(temp[3]);
                    m_idx.push_back(temp[2]);
                }
            }
            break;
        default:
            break;
        }


    }
}

void ObjLoader::check()
{
    for each (XYZ var in m_vt)
    {
        printf("%f,%f,%f\n", var.x, var.y, var.z);
    }

    for each(UV var in m_uv)
    {
        printf("%f,%f\n", var.u, var.v);

    }

    for each (XYZ var in m_vn)
    {
        printf("%f,%f,%f\n", var.x, var.y, var.z);
    }

    for each(faceindex var in m_idx)
    {
        printf("%d,%d,%d\n", var.idxV,  var.idxVt, var.idxVn);

    }

}

void ObjLoader::checkingoptimize()
{
    //cout << "오리지날 : "<< m_vertice.size() << endl;
    //cout << "최적화 : "<<m_refinedVertice.size() <<endl;
    //cout << "인덱스 : "<<m_indice.size() << endl;
    //meshData lastunopdata =  m_vertice[m_vertice.size() - 1];
    //meshData lastopdata = m_refinedVertice[m_indice[m_indice.size() - 1]];
    //meshData firstOpdata = m_refinedVertice[m_indice[0]];
    //
    //cout << "오리지날 마지막 데이타" << endl;
    //showPos(lastunopdata);
    //cout << "최적화 마지막 데이타" << endl;
    //showPos(lastopdata);
    //cout << "최적화 처음  데이타" << endl;
    //showPos(firstOpdata);
    //
    //for each (unsigned int var in m_indice)
    //{
    //  cout << var << endl;
    //}




}

void ObjLoader::showPos(meshData data)
{

    //cout << "x : " << data.pos.x << "y: " << data.pos.y << "z: " << data.pos.z << endl;
    cout << "x : " << data.tangent.x << "y: " << data.tangent.y << "z: " << data.tangent.z << endl;

}

void ObjLoader::calculateTangent()
{
    assert(m_refinedVertice.size() && "최적화 파싱먼저 하시오");
    assert(!(m_indice.size() % 3) && "3으로 나누어 떨어지지 않는 삼각형 리스트가 있을리가 없지.");

    struct data {
        XMFLOAT3 pos;
        XMFLOAT2 uv;
        data() { pos = XMFLOAT3(0, 0, 0); uv = XMFLOAT2(0, 0); }
        data operator-(data& in)
        {
            data result;
            result.pos.x = pos.x - in.pos.x;
            result.pos.y = pos.y - in.pos.y;
            result.pos.z = pos.z - in.pos.z;

            result.uv.x = uv.x - in.uv.x;
            result.uv.y = uv.y - in.uv.y;
            return result;
        }
    };

    struct tangent {
        XMFLOAT3 tan;
        XMFLOAT3 binor;
        XMFLOAT3 normal;
        int addCount;
        tangent() { normal = XMFLOAT3(0, 0, 0); tan = XMFLOAT3(0, 0, 0); addCount = 0; binor = XMFLOAT3(0, 0, 0); }
    };


    vector<tangent> verPerTan;
    verPerTan.assign(m_refinedVertice.size(), tangent());

    data triagle[3];
    int loopcnt = m_indice.size() / 3;
    for(int i=0;i<loopcnt;i++)
    {
        for (int k = 0; k < 3; k++)
        {
            triagle[k].pos = m_refinedVertice[m_indice[(i*3)+k]].pos;
            triagle[k].uv = m_refinedVertice[m_indice[(i*3)+k]].UV;
        }

        XMVECTOR v[3];
        XMVECTOR uv[3];
        for (int i = 0; i < 3; i++)
        {
            v[i] = XMLoadFloat3(&triagle[i].pos);
            uv[i] = XMLoadFloat2(&triagle[i].uv);
        }

        XMVECTOR e0, e1,dUv0,dUv1;
        e0 = v[1] - v[0];
        e1 = v[2] - v[0];
        dUv0 = uv[1] - uv[0];
        dUv1 = uv[2] - uv[0];
        XMVECTOR Normal = XMVector3Cross(e0, e1);

        float det = dUv0.m128_f32[0] * dUv1.m128_f32[1] - dUv0.m128_f32[1] * dUv1.m128_f32[0];
        XMVECTOR nullvector = XMVectorSet(0, 0, 0, 0);
        XMMATRIX uvMatrix, eMatrix, TBMatrix;
        // rowmajor matrix
        uvMatrix = XMMATRIX(dUv0, dUv1 ,nullvector, nullvector);
        eMatrix = XMMATRIX(e0, e1, nullvector, nullvector);
        TBMatrix = XMMATRIX(nullvector, nullvector, nullvector, nullvector);
        // cal det
        float temp = uvMatrix.r[0].m128_f32[0];
        uvMatrix.r[0].m128_f32[0] = uvMatrix.r[1].m128_f32[1];
        uvMatrix.r[1].m128_f32[1] = temp;
        temp = uvMatrix.r[0].m128_f32[1];
        uvMatrix.r[0].m128_f32[1] = -uvMatrix.r[1].m128_f32[0];
        uvMatrix.r[1].m128_f32[0] = -temp;
        //

        //calculate TB
        uvMatrix *= det;
        TBMatrix = uvMatrix*eMatrix;

        XMVECTOR tan;
        XMVECTOR bi;
        XMVECTOR XMverpertan;
        XMVECTOR XMverperbi;
        XMVECTOR XMNormal;
        // averaging TBN
        for (int k = 0; k < 3; k++)
        {
            XMverpertan = XMLoadFloat3(&verPerTan[m_indice[(i * 3) + k]].tan);
            XMverperbi = XMLoadFloat3(&verPerTan[m_indice[(i * 3) + k]].binor);
            XMNormal = XMLoadFloat3(&verPerTan[m_indice[(i * 3) + k]].normal);
            XMverpertan += TBMatrix.r[0];
            XMverperbi += TBMatrix.r[1];
            XMNormal += Normal;
            XMStoreFloat3(&verPerTan[m_indice[(i * 3) + k]].tan, XMverpertan);
            XMStoreFloat3(&verPerTan[m_indice[(i * 3) + k]].binor, XMverperbi);
            XMStoreFloat3(&verPerTan[m_indice[(i * 3) + k]].normal, XMNormal);
            verPerTan[m_indice[(i * 3) + k]].addCount++;
        }
    }

    // averaging TBN
    for each (tangent var in verPerTan)
    {
        int addcount = var.addCount;
        var.binor.x /= addcount;
        var.binor.y /= addcount;
        var.binor.z /= addcount;

        var.tan.x /= addcount;
        var.tan.y /= addcount;
        var.tan.z /= addcount;
    }

    //Gram-Schmidt 
    for (int i = 0; i < m_refinedVertice.size(); i++)
    {
        XMVECTOR N, T, B;
        N = XMLoadFloat3(&verPerTan[i].normal);
        T = XMLoadFloat3(&verPerTan[i].tan);
        B = XMLoadFloat3(&verPerTan[i].binor);

        N = XMVector3Normalize(N);
        T = XMVector3Normalize(T);
        B = XMVector3Normalize(B);

        T = XMVector3Normalize(T - (XMVector3Dot(N, T)*N));
        B = XMVector3Normalize(B - (XMVector3Dot(T, B)*T));
        B = XMVector3Normalize(B - (XMVector3Dot(N, B)*N));



        XMStoreFloat3(&m_refinedVertice[i].tangent, T);
        XMStoreFloat3(&m_refinedVertice[i].normal, N);
    }





    ////test//
    //XMMATRIX rowMajor, columnMajor;
    //
    //rowMajor = XMMATRIX(1.0f, 1.0f, 1.0f, 1.0f
    //  , 0.0f, 0.0f, 0.0f, 0.0f
    //  , 0.0f, 0.0f, 0.0f, 0.0f
    //  , 0.0f, 0.0f, 0.0f, 0.0f);
    //columnMajor = XMMATRIX(1, 0, 0, 0,
    //  1, 0, 0, 0,
    //  1, 0, 0, 0,
    //  1, 0, 0, 0);
    //
    //XMMATRIX result;
    //
    //result=rowMajor*columnMajor;
    // m[1,1] = 4
    // row*column
    // vector의 dot product를 이용한다.


}

void ObjLoader::loadVertex()
{
    meshData vertex;

    auto it = m_idx.begin();
    for (; it != m_idx.end(); it++)
    {
        vertex.pos.x = m_vt[it->idxV].x;
        vertex.pos.y = m_vt[it->idxV].y;
        vertex.pos.z = m_vt[it->idxV].z;

        vertex.normal.x = m_vn[it->idxVn].x;
        vertex.normal.y = m_vn[it->idxVn].y;
        vertex.normal.z = m_vn[it->idxVn].z;

        vertex.UV.x = m_uv[it->idxVt].u;
        vertex.UV.y = m_uv[it->idxVt].v;
        m_vertice.push_back(vertex);

    }
}

// optimize the vertex
// by findout same vertice , remove it and replace it by indexing
void ObjLoader::optimize()
{
    unsigned int* deleteindex = new unsigned int[m_vertice.size()];
    unsigned int* indice = new unsigned int[m_vertice.size()];
    unsigned int numofpoints = 0;
    memset(deleteindex, 0, sizeof(deleteindex));
    for (int i = 0; i < m_vertice.size(); i++)
    {

        bool found = false;
        meshData pivot = m_vertice[i];

        for (int k = 0; k < m_vertice.size(); k++)
        {

            if (pivot == m_vertice[k] && i != k)
            {

                if (i < k)
                {
                    break;
                }
                else
                {
                    found = true;
                    indice[i] = indice[k];
                    deleteindex[i] = true;
                    break;
                }
            }
        }


        if (found == false)
        {
            deleteindex[i] = false;
            indice[i] = numofpoints;
            numofpoints++;
        }
    }

    for (int i = 0; i < m_vertice.size() ; i++)
    {
        m_indice.push_back(indice[i]);
    }

    for (int i = 0; i < m_vertice.size() ; i++)
    {
        if (!deleteindex[i])
        {
            m_refinedVertice.push_back(m_vertice[i]);
        }
    }



    delete[] deleteindex;
    delete[] indice;
}

any debug suggestion for this? plz...

\$\endgroup\$
2
  • \$\begingroup\$ How are your UVs laid out? What does your normal map look like? \$\endgroup\$ Commented Aug 15, 2017 at 11:32
  • \$\begingroup\$ Have you looked at the code in DirectXMesh? \$\endgroup\$ Commented Aug 15, 2017 at 18:46

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.