Exemple #1
0
bool TileAssembler::calculateTransformedBound(ModelSpawn &spawn)
{
    std::string modelFilename(iSrcDir);
    modelFilename.push_back('/');
    modelFilename.append(spawn.name);

    ModelPosition modelPosition;
    modelPosition.iDir = spawn.iRot;
    modelPosition.iScale = spawn.iScale;
    modelPosition.init();

    WorldModel_Raw raw_model;
    if (!raw_model.Read(modelFilename.c_str()))
        return false;

    G3D::uint32 groups = raw_model.groupsArray.size();
#ifdef _DEBUG
    if (groups != 1)
        printf("Warning: '%s' does not seem to be a M2 model!\n", modelFilename.c_str());
#endif

    AABox modelBound;
    bool boundEmpty=true;

    for (G3D::uint32 g=0; g<groups; ++g) // should be only one for M2 files...
    {
        std::vector<Vector3>& vertices = raw_model.groupsArray[g].vertexArray;

        if (vertices.empty())
        {
            std::cout << "error: model '" << spawn.name << "' has no geometry!" << std::endl;
            continue;
        }

        G3D::uint32 nvectors = vertices.size();
        for (G3D::uint32 i = 0; i < nvectors; ++i)
        {
            Vector3 v = modelPosition.transform(vertices[i]);

            if (boundEmpty)
                modelBound = AABox(v, v), boundEmpty=false;
            else
                modelBound.merge(v);
        }
    }
    spawn.iBound = modelBound + spawn.iPos;
    spawn.flags |= MOD_HAS_BOUND;
    return true;
}
Exemple #2
0
    bool TileAssembler::calculateTransformedBound(ModelSpawn &spawn)
    {
        std::string modelFilename(iSrcDir);
        modelFilename.push_back('/');
        modelFilename.append(spawn.name);

        ModelPosition modelPosition;
        modelPosition.iDir = spawn.iRot;
        modelPosition.iScale = spawn.iScale;
        modelPosition.init();

        FILE* rf = fopen(modelFilename.c_str(), "rb");
        if (!rf)
        {
            printf("ERROR: Can't open model file: %s\n", modelFilename.c_str());
            return false;
        }

        AABox modelBound;
        bool boundEmpty=true;
        char ident[8];

        int readOperation = 1;

        // temporary use defines to simplify read/check code (close file and return at fail)
        #define READ_OR_RETURN(V, S) if (fread((V), (S), 1, rf) != 1) { \
                                        fclose(rf); printf("readfail, op = %i\n", readOperation); return(false); }readOperation++;
        // only use this for array deletes
        #define READ_OR_RETURN_WITH_DELETE(V, S) if (fread((V), (S), 1, rf) != 1) { \
                                        fclose(rf); printf("readfail, op = %i\n", readOperation); delete[] V; return(false); }readOperation++;

        #define CMP_OR_RETURN(V, S)  if (strcmp((V), (S)) != 0)        { \
                                        fclose(rf); printf("cmpfail, %s!=%s\n", V, S);return(false); }

        READ_OR_RETURN(&ident, 8);
        CMP_OR_RETURN(ident, "VMAP003");

        // we have to read one int. This is needed during the export and we have to skip it here
        uint32 tempNVectors;
        READ_OR_RETURN(&tempNVectors, sizeof(tempNVectors));

        uint32 groups, wmoRootId;
        char blockId[5];
        blockId[4] = 0;
        int blocksize;
        float *vectorarray = 0;

        READ_OR_RETURN(&groups, sizeof(uint32));
        READ_OR_RETURN(&wmoRootId, sizeof(uint32));
        if (groups != 1) printf("Warning: '%s' does not seem to be a M2 model!\n", modelFilename.c_str());

        for (uint32 g=0; g<groups; ++g) // should be only one for M2 files...
        {
            fseek(rf, 3*sizeof(uint32) + 6*sizeof(float), SEEK_CUR);

            READ_OR_RETURN(&blockId, 4);
            CMP_OR_RETURN(blockId, "GRP ");
            READ_OR_RETURN(&blocksize, sizeof(int));
            fseek(rf, blocksize, SEEK_CUR);

            // ---- indexes
            READ_OR_RETURN(&blockId, 4);
            CMP_OR_RETURN(blockId, "INDX");
            READ_OR_RETURN(&blocksize, sizeof(int));
            fseek(rf, blocksize, SEEK_CUR);

            // ---- vectors
            READ_OR_RETURN(&blockId, 4);
            CMP_OR_RETURN(blockId, "VERT");
            READ_OR_RETURN(&blocksize, sizeof(int));
            uint32 nvectors;
            READ_OR_RETURN(&nvectors, sizeof(uint32));

            if (nvectors >0)
            {
                vectorarray = new float[nvectors*3];
                READ_OR_RETURN_WITH_DELETE(vectorarray, nvectors*sizeof(float)*3);
            }
            else
            {
                std::cout << "error: model '" << spawn.name << "' has no geometry!" << std::endl;
                fclose(rf);
                return false;
            }

            for (uint32 i=0, indexNo=0; indexNo<nvectors; indexNo++, i+=3)
            {
                Vector3 v = Vector3(vectorarray[i+0], vectorarray[i+1], vectorarray[i+2]);
                v = modelPosition.transform(v);

                if (boundEmpty)
                    modelBound = AABox(v, v), boundEmpty=false;
                else
                    modelBound.merge(v);
            }
            delete[] vectorarray;
            // drop of temporary use defines
            #undef READ_OR_RETURN
            #undef READ_OR_RETURN_WITH_DELETE
            #undef CMP_OR_RETURN
        }
        spawn.iBound = modelBound + spawn.iPos;
        spawn.flags |= MOD_HAS_BOUND;
        fclose(rf);
        return true;
    }