Ejemplo n.º 1
0
int MeshObjReader::read(const wchar_t* file, TriangleMesh& mesh, 
                bool centerize, bool reversetglrot)
{
    using namespace std;

    ifstream fin(file);
    if ( fin.fail() ) return E_FAIL;
    
    char text[1024];
    vector<D3DXVECTOR3>     vtx;    // temporary space to put the vertex
    vector<D3DXVECTOR3>    nml;
    vector<Tuple3ui>    tgl;
    vector<Tuple3ui>    tNml;

    int l = 1;
    fin.getline(text, 1024);
    while ( !fin.fail() )
    {
        vector<string> tokens = sploosh::tokenize(string(text));
        if ( tokens.empty() ) 
        {
            fin.getline(text, 1024);
            ++ l;
            continue;
        }

        if ( tokens[0] == "v" )
        {
            if ( tokens.size() != 4 )
            {
				printf("(A) Incorrect file format at Line %d.\n", l);
                exit(1);
            }
			vtx.push_back(D3DXVECTOR3(sploosh::Double(tokens[1]),
                                  -sploosh::Double(tokens[3]),
                                  sploosh::Double(tokens[2])));
        }
        else if ( tokens[0] == "vn" )
        {
            if ( tokens.size() != 4 )
            {
                printf("(B) Incorrect file format at Line %d.\n", l);
                exit(1);
            }
            nml.push_back(D3DXVECTOR3(sploosh::Double(tokens[1]),
                                   -sploosh::Double(tokens[3]),
                                   sploosh::Double(tokens[2])));
			D3DXVec3Normalize(&(nml.back()), &nml.back());
        }
        else if ( tokens[0] == "f" )
        {
            if ( tokens.size() != 4 )
            {
                printf("(C) Incorrect file format at Line %d (# of fields is larger than 3)\n", l);
                exit(1);
            }

            vector<string> ts0 = sploosh::split(tokens[1], '/');
            vector<string> ts1 = sploosh::split(tokens[2], '/');
            vector<string> ts2 = sploosh::split(tokens[3], '/');

            if ( ts0.size() != ts1.size() || ts1.size() != ts2.size() )
            {
                printf("(D) Incorrect file format at Line %d.\n", l);
                exit(1);
            }

            tgl.push_back(Tuple3ui(sploosh::Int(ts0[0])-1,
                                   sploosh::Int(ts1[0])-1,
                                   sploosh::Int(ts2[0])-1));
            if ( ts0.size() > 2 )
                tNml.push_back(Tuple3ui(sploosh::Int(ts0[2])-1,
                                        sploosh::Int(ts1[2])-1,
                                        sploosh::Int(ts2[2])-1));
        }

        fin.getline(text, 1024);
        ++ l;
    }

    fin.close();

    /* No triangles at all */
    if ( tgl.empty() ) printf("THERE IS NO TRIANGLE MESHS AT ALL!\n");

    /* Centerize the objects */
    if ( centerize )
    {
		D3DXVECTOR3 maxPt(
			-std::numeric_limits<float>::infinity(), 
			-std::numeric_limits<float>::infinity(), 
			-std::numeric_limits<float>::infinity()), 
                minPt(
				std::numeric_limits<float>::infinity(), 
				std::numeric_limits<float>::infinity(), 
				std::numeric_limits<float>::infinity());
        for(size_t i = 0;i < vtx.size();++ i)
        {
            maxPt.x = max(vtx[i].x, maxPt.x);
            maxPt.y = max(vtx[i].y, maxPt.y);
            maxPt.z = max(vtx[i].z, maxPt.z);

            minPt.x = min(vtx[i].x, minPt.x);
            minPt.y = min(vtx[i].y, minPt.y);
            minPt.z = min(vtx[i].z, minPt.z);
        }

		D3DXVECTOR3 center = (maxPt + minPt) * 0.5;
        for(size_t i = 0;i < vtx.size();++ i)
            vtx[i] -= center;
    }

    if ( nml.empty() )
    {
		nml.resize(vtx.size());
        for(size_t i = 0;i < tgl.size();++ i)
        {
			D3DXVECTOR3 v0 = vtx[tgl[i][0]];
			D3DXVECTOR3 v1 = vtx[tgl[i][1]];
			D3DXVECTOR3 v2 = vtx[tgl[i][2]];

			D3DXVECTOR3 e0 = v1 - v0;
			D3DXVECTOR3 e1 = v2 - v0;
			D3DXVECTOR3 norm;
			D3DXVec3Cross(&norm, &e0, &e1);
			nml[tgl[i][0]] += norm;
			nml[tgl[i][1]] += norm;
			nml[tgl[i][2]] += norm;
		}

        for(size_t i = 0;i < nml.size();++ i)
        {
			if(D3DXVec3LengthSq(&nml[i]) == 0) nml[i] = D3DXVECTOR3(0, 1, 0);
			D3DXVec3Normalize(&nml[i], &nml[i]);
		}

        for(size_t i = 0;i < vtx.size();++ i)
            mesh.add_vertex_normal(vtx[i], nml[i]);
    }
    else
    {
		vector<D3DXVECTOR3> nmlmap(vtx.size(), D3DXVECTOR3(0,0,0));

        for(size_t i = 0;i < tgl.size();++ i)
        {
			nmlmap[tgl[i][0]] += nml[tNml[i][0]];
			nmlmap[tgl[i][1]] += nml[tNml[i][1]];
			nmlmap[tgl[i][2]] += nml[tNml[i][2]];
        }

        for(size_t i = 0;i < vtx.size();++ i) {
			D3DXVec3Normalize(&nmlmap[i], &nmlmap[i]);
            mesh.add_vertex_normal(vtx[i], nmlmap[i]);
		}
    }

    if ( reversetglrot )
        for(size_t i = 0;i < tgl.size();++ i)
            mesh.add_triangle(tgl[i][0], tgl[i][2], tgl[i][1]);
    else
        for(size_t i = 0;i < tgl.size();++ i)
            mesh.add_triangle(tgl[i][0], tgl[i][1], tgl[i][2]);

    return 0;
}