Has this code the same function as before?

Started by
1 comment, last by lucky6969b 9 years, 10 months ago

The code is to get the indices from the .obj file that make up a face


static int parseFace(char* row, int* data, int n, int vcnt)
{
    int j = 0;
    while (*row != '\0')
    {
        // Skip initial white space
        while (*row != '\0' && (*row == ' ' || *row == '\t'))
            row++;
        char* s = row;
        // Find vertex delimiter and terminated the string there for conversion.
        while (*row != '\0' && *row != ' ' && *row != '\t')
        {
            if (*row == '/') *row = '\0';
            row++;
        }
        if (*s == '\0')
            continue;
        int vi = atoi(s);
        data[j++] = vi < 0 ? vi+vcnt : vi-1;
        if (j >= n) return j;
    }
    return j;
}
 
static char* parseRow(char* buf, char* bufEnd, char* row, int len)
{
    bool cont = false;
    bool start = true;
    bool done = false;
    int n = 0;
    while (!done && buf < bufEnd)
    {
        char c = *buf;
        buf++;
        // multirow
        switch (c)
        {
            case '\\':
                cont = true; // multirow
                break;
            case '\n':
                if (start) break;
                done = true;
                break;
            case '\r':
                break;
            case '\t':
            case ' ':
                if (start) break;
            default:
                start = false;
                cont = false;
                row[n++] = c;
                if (n >= len-1)
                    done = true;
                break;
        }
    }
    row[n] = '\0';
    return buf;
}
 
 
void rcMeshLoaderX::addVertex(float x, float y, float z, int& cap)
{
    if (m_vertCount+1 > cap)
    {
        cap = !cap ? 8 : cap*2;
        float* nv = new float[cap*3];
        if (m_vertCount)
            memcpy(nv, m_verts, m_vertCount*3*sizeof(float));
        delete [] m_verts;
        m_verts = nv;
    }
    float* dst = &m_verts[m_vertCount*3];
    *dst++ = x*m_scale;
    *dst++ = y*m_scale;
    *dst++ = z*m_scale;
    m_vertCount++;
}
 
 
void rcMeshLoaderX::addTriangle(int a, int b, int c, int& cap)
{
    if (m_triCount+1 > cap)
    {
        cap = !cap ? 8 : cap*2;
        int* nv = new int[cap*3];
        if (m_triCount)
            memcpy(nv, m_tris, m_triCount*3*sizeof(int));
        delete [] m_tris;
        m_tris = nv;
    }
    int* dst = &m_tris[m_triCount*3];
    *dst++ = a;
    *dst++ = b;
    *dst++ = c;
    m_triCount++;
}

==================================

to be replaced


bool rcMeshLoaderX::load(const char* filename)
{
    char* buf = 0;
    FILE* fp = fopen(filename, "rb");
    if (!fp)
        return false;
    fseek(fp, 0, SEEK_END);
    int bufSize = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    buf = new char[bufSize];
    if (!buf)
    {
        fclose(fp);
        return false;
    }
    fread(buf, bufSize, 1, fp);
    fclose(fp);

    char* src = buf;
    char* srcEnd = buf + bufSize;
    char row[512];
    int face[32];
    float x,y,z;
    int nv;
    int vcap = 0;
    int tcap = 0;
 
    while (src < srcEnd)
    {
        // Parse one row
        row[0] = '\0';
        src = parseRow(src, srcEnd, row, sizeof(row)/sizeof(char));
        // Skip comments
        if (row[0] == '#') continue;
        if (row[0] == 'v' && row[1] != 'n' && row[1] != 't')
        {
            // Vertex pos
            sscanf(row+1, "%f %f %f", &x, &y, &z);
            addVertex(x, y, z, vcap);
        }
        if (row[0] == 'f')
        {
            // Faces
            nv = parseFace(row+1, face, 32, m_vertCount);
            for (int i = 2; i < nv; ++i)
            {
                const int a = face[0];
                const int b = face[i-1];
                const int c = face[i];
                if (a < 0 || a >= m_vertCount || b < 0 || b >= m_vertCount || c < 0 || c >= m_vertCount)
                    continue;
                addTriangle(a, b, c, tcap);
            }
        }
    }
    delete [] buf;

    // Calculate normals.
    m_normals = new float[m_triCount*3];
    for (int i = 0; i < m_triCount*3; i += 3)
    {
        const float* v0 = &m_verts[m_tris[i]*3];
        const float* v1 = &m_verts[m_tris[i+1]*3];
        const float* v2 = &m_verts[m_tris[i+2]*3];
        float e0[3], e1[3];
        for (int j = 0; j < 3; ++j)
        {
            e0[j] = v1[j] - v0[j];
            e1[j] = v2[j] - v0[j];
        }
        float* n = &m_normals[i];
        n[0] = e0[1]*e1[2] - e0[2]*e1[1];
        n[1] = e0[2]*e1[0] - e0[0]*e1[2];
        n[2] = e0[0]*e1[1] - e0[1]*e1[0];
        float d = sqrtf(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]);
        if (d > 0)
        {
            d = 1.0f/d;
            n[0] *= d;
            n[1] *= d;
            n[2] *= d;
        }
    }
    
    strncpy(m_filename, filename, sizeof(m_filename));
    m_filename[sizeof(m_filename)-1] = '\0';
    
    return true;
}

===================================================

Replaced by


rcMeshLoaderX::rcMeshLoaderX(CMesh *mesh) {
    LPDIRECT3DVERTEXBUFFER9 vb;
    LPDIRECT3DINDEXBUFFER9 ib;
    void *pVertices;
    int vcap, tcap = 0;

    auto dxMesh = mesh->GetStaticMesh();

    D3DVERTEXELEMENT9 decl[MAXD3DDECLLENGTH];
    dxMesh->GetDeclaration(decl);

    WORD offsetToPosition = 0;

    for (UINT i = 0; i < MAXD3DDECLLENGTH; ++i)
    {
        if (D3DDECLUSAGE_POSITION == decl[i].Usage)
        {
            offsetToPosition = decl[i].Offset;
        }
    }


    // Get Vertex Information
    DWORD vertStride = dxMesh->GetNumBytesPerVertex();
    DWORD numVerts = dxMesh->GetNumVertices();
    
    BYTE* pIndices;    
    dxMesh->LockIndexBuffer(0, (LPVOID*)&pIndices);

    for (DWORD i = 0; i < numVerts/3; ++i) {
        // each vertex has an index, 3 indices become an triangle
        int index0 = *(int*)(&pIndices[vertStride * i + offsetToPosition]);
        int index1 = *(int*)(&pIndices[vertStride * i + offsetToPosition + 1]);
        int index2 = *(int*)(&pIndices[vertStride * i + offsetToPosition + 2]);

        addTriangle(index0, index1, index2, tcap);
    }

    BYTE* pVert;
    dxMesh->UnlockIndexBuffer();
    
    dxMesh->LockVertexBuffer(0, (LPVOID*)&pVert);
    for (DWORD i = 0; i < numVerts; ++i)
    {
        D3DXVECTOR3 currentPos = *(D3DXVECTOR3*)(&pVert[vertStride * i + offsetToPosition]);

        // vertices
        //x
        const float *v0 = &currentPos.x;
        //y
        const float *v1 = &currentPos.y;
        //z
        const float *v2 = &currentPos.z;

        addVertex(*v0, *v1, *v2, vcap);
        

        float e0[3], e1[3];
        for (int j = 0; j < 3; ++j)
        {
            e0[j] = v1[j] - v0[j];
            e1[j] = v2[j] - v0[j];
        }
        float* n = &m_normals[i];
        n[0] = e0[1]*e1[2] - e0[2]*e1[1];
        n[1] = e0[2]*e1[0] - e0[0]*e1[2];
        n[2] = e0[0]*e1[1] - e0[1]*e1[0];
        float d = sqrtf(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]);
        if (d > 0)
        {
            d = 1.0f/d;
            n[0] *= d;
            n[1] *= d;
            n[2] *= d;
        }         

    }
    
    dxMesh->UnlockVertexBuffer();   
}

I was not quite familiar with the back-culling stuff and other things that

have to be considered on vertex level, so please give me some hints on how correct

this code could be....

Thanks

Jack

Advertisement

First thing wrong that i see is obtaining indices, try something like this:


DWORD indStride = sizeof(WORD);
DWORD opt = dxMesh->GetOptions();
if((opt & D3DXMESH_32BIT) == D3DXMESH_32BIT)
{
    indStride = sizeof(DWORD);
}
BYTE* pIndices;    
dxMesh->LockIndexBuffer(0, (LPVOID*)&pIndices);
DWORD numInd = dxMesh->GetNumFaces() * 3;
for(DWORD i = 0; i < numInd; i += 3)
{
    int index0 = *(int*)(&pIndices[indStride * i + 0]);
        int index1 = *(int*)(&pIndices[indStride * i + 1]);
        int index2 = *(int*)(&pIndices[indStride * i + 2]);
...
}
...

edit: made a mistake, corrected

Works like a charm!

Thanks

Jack

This topic is closed to new replies.

Advertisement