bool WorldModel_Raw::Read(const char* path)
    {
        FILE* rf = fopen(path, "rb");
        if (!rf)
        {
            printf("ERROR: Can't open raw model file: %s\n", path);
            return false;
        }

        char ident[8];
        int readOperation = 0;

        READ_OR_RETURN(&ident, 8);
        CMP_OR_RETURN(ident, RAW_VMAP_MAGIC);

        // 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;
        READ_OR_RETURN(&groups, sizeof(uint32));
        READ_OR_RETURN(&RootWMOID, sizeof(uint32));

        groupsArray.resize(groups);
        bool succeed = true;
        for (uint32 g = 0; g < groups && succeed; ++g)
            { succeed = groupsArray[g].Read(rf); }

        fclose(rf);
        return succeed;
    }
Beispiel #2
0
	//=================================================================
	bool TileAssembler::convertRawFile(const std::string& pModelFilename)
	{
		bool success = true;
		std::string filename = iSrcDir;
		if (filename.length() >0)
			filename.append("/");
		filename.append(pModelFilename);
		FILE *rf = fopen(filename.c_str(), "rb");

		if (!rf)
		{
			printf("ERROR: Can't open model file in form: %s",pModelFilename.c_str());
			printf("...							or form: %s",filename.c_str() );
			return false;
		}

		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++;
		#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;
		uint32 RootWMOID;
		char blockId[5];
		blockId[4] = 0;
		int blocksize;

		READ_OR_RETURN(&groups, sizeof(uint32));
		READ_OR_RETURN(&RootWMOID, sizeof(uint32));

		std::vector<GroupModel> groupsArray;

		for (uint32 g=0; g<groups; ++g)
		{
			std::vector<MeshTriangle> triangles;
			std::vector<Vector3> vertexArray;

			uint32 mogpflags, GroupWMOID;
			READ_OR_RETURN(&mogpflags, sizeof(uint32));
			READ_OR_RETURN(&GroupWMOID, sizeof(uint32));

			float bbox1[3], bbox2[3];
			READ_OR_RETURN(bbox1, sizeof(float)*3);
			READ_OR_RETURN(bbox2, sizeof(float)*3);

			uint32 liquidflags;
			READ_OR_RETURN(&liquidflags, sizeof(uint32));

			// will this ever be used? what is it good for anyway??
			uint32 branches;
			READ_OR_RETURN(&blockId, 4);
			CMP_OR_RETURN(blockId, "GRP ");
			READ_OR_RETURN(&blocksize, sizeof(int));
			READ_OR_RETURN(&branches, sizeof(uint32));
			for (uint32 b=0; b<branches; ++b)
			{
				uint32 indexes;
				// indexes for each branch (not used jet)
				READ_OR_RETURN(&indexes, sizeof(uint32));
			}

			// ---- indexes
			READ_OR_RETURN(&blockId, 4);
			CMP_OR_RETURN(blockId, "INDX");
			READ_OR_RETURN(&blocksize, sizeof(int));
			uint32 nindexes;
			READ_OR_RETURN(&nindexes, sizeof(uint32));
			if (nindexes >0)
			{
				uint16 *indexarray = new uint16[nindexes];
				READ_OR_RETURN(indexarray, nindexes*sizeof(uint16));
				for (uint32 i=0; i<nindexes; i+=3)
				{
					triangles.push_back(MeshTriangle(indexarray[i], indexarray[i+1], indexarray[i+2]));
				}
				delete[] indexarray;
			}

			// ---- 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)
			{
				float *vectorarray = new float[nvectors*3];
				READ_OR_RETURN(vectorarray, nvectors*sizeof(float)*3);
				for (uint32 i=0; i<nvectors; ++i)
				{
					vertexArray.push_back( Vector3(vectorarray + 3*i) );
				}
				delete[] vectorarray;
			}
			// ----- liquid
			WmoLiquid *liquid = 0;
			if (liquidflags& 1)
			{
				WMOLiquidHeader hlq;
				READ_OR_RETURN(&blockId, 4);
				CMP_OR_RETURN(blockId, "LIQU");
				READ_OR_RETURN(&blocksize, sizeof(int));
				READ_OR_RETURN(&hlq, sizeof(WMOLiquidHeader));
				liquid = new WmoLiquid(hlq.xtiles, hlq.ytiles, Vector3(hlq.pos_x, hlq.pos_y, hlq.pos_z), hlq.type);
				uint32 size = hlq.xverts*hlq.yverts;
				READ_OR_RETURN(liquid->GetHeightStorage(), size*sizeof(float));
				size = hlq.xtiles*hlq.ytiles;
				READ_OR_RETURN(liquid->GetFlagsStorage(), size);
			}

			groupsArray.push_back(GroupModel(mogpflags, GroupWMOID, AABox(Vector3(bbox1), Vector3(bbox2))));
			groupsArray.back().setMeshData(vertexArray, triangles);
			groupsArray.back().setLiquidData(liquid);

			// drop of temporary use defines
			#undef READ_OR_RETURN
			#undef CMP_OR_RETURN

		}
		fclose(rf);

		// write WorldModel
		WorldModel model;
		model.setRootWmoID(RootWMOID);
		if (groupsArray.size())
		{
			model.setGroupModels(groupsArray);
			success = model.writeFile(iDestDir + "/" + pModelFilename + ".vmo");
		}

		//std::cout << "readRawFile2: '" << pModelFilename << "' tris: " << nElements << " nodes: " << nNodes << std::endl;
		return success;
	}
Beispiel #3
0
	bool TileAssembler::calculateTransformedBound(ModelSpawn &spawn)
	{
		std::string modelFilename = iSrcDir + "/" + 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++;
		#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(vectorarray, nvectors*sizeof(float)*3);
			}
			else
			{
				std::cout << "error: model '" << spawn.name << "' has no geometry!" << std::endl;
				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 CMP_OR_RETURN
		}
		spawn.iBound = modelBound + spawn.iPos;
		spawn.flags |= MOD_HAS_BOUND;
		fclose(rf);
		return true;
	}
    bool GroupModel_Raw::Read(FILE* rf)
    {
        char blockId[5];
        blockId[4] = 0;
        int blocksize;
        int readOperation = 0;

        READ_OR_RETURN(&mogpflags, sizeof(uint32));
        READ_OR_RETURN(&GroupWMOID, sizeof(uint32));

        Vector3 vec1, vec2;
        READ_OR_RETURN(&vec1, sizeof(Vector3));
        READ_OR_RETURN(&vec2, sizeof(Vector3));
        bounds.set(vec1, vec2);

        READ_OR_RETURN(&liquidflags, sizeof(uint32));

        // will this ever be used? what is it good for anyway??
        uint32 branches;
        READ_OR_RETURN(&blockId, 4);
        CMP_OR_RETURN(blockId, "GRP ");
        READ_OR_RETURN(&blocksize, sizeof(int));
        READ_OR_RETURN(&branches, sizeof(uint32));
        for (uint32 b = 0; b < branches; ++b)
        {
            uint32 indexes;
            // indexes for each branch (not used jet)
            READ_OR_RETURN(&indexes, sizeof(uint32));
        }

        // ---- indexes
        READ_OR_RETURN(&blockId, 4);
        CMP_OR_RETURN(blockId, "INDX");
        READ_OR_RETURN(&blocksize, sizeof(int));
        uint32 nindexes;
        READ_OR_RETURN(&nindexes, sizeof(uint32));
        if (nindexes > 0)
        {
            uint16* indexarray = new uint16[nindexes];
            if (fread(indexarray, nindexes * sizeof(uint16), 1, rf) != 1)
            {
                fclose(rf);
                delete[] indexarray;
                printf("readfail, op = %i\n", readOperation);
                return false;
            }
            triangles.reserve(nindexes / 3);
            for (uint32 i = 0; i < nindexes; i += 3)
            {
                triangles.push_back(MeshTriangle(indexarray[i], indexarray[i + 1], indexarray[i + 2]));
            }
            delete[] indexarray;
        }

        // ---- 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)
        {
            float* vectorarray = new float[nvectors * 3];
            if (fread(vectorarray, nvectors * sizeof(float) * 3, 1, rf) != 1)
            {
                fclose(rf);
                delete[] vectorarray;
                printf("readfail, op = %i\n", readOperation);
                return false;
            }

            for (uint32 i = 0; i < nvectors; ++i)
            {
                vertexArray.push_back(Vector3(vectorarray + 3 * i));
            }
            delete[] vectorarray;
        }

        // ----- liquid
        liquid = 0;
        if (liquidflags & 1)
        {
            WMOLiquidHeader hlq;
            READ_OR_RETURN(&blockId, 4);
            CMP_OR_RETURN(blockId, "LIQU");
            READ_OR_RETURN(&blocksize, sizeof(int));
            READ_OR_RETURN(&hlq, sizeof(WMOLiquidHeader));
            liquid = new WmoLiquid(hlq.xtiles, hlq.ytiles, Vector3(hlq.pos_x, hlq.pos_y, hlq.pos_z), hlq.type);
            uint32 size = hlq.xverts * hlq.yverts;
            READ_OR_RETURN(liquid->GetHeightStorage(), size * sizeof(float));
            size = hlq.xtiles * hlq.ytiles;
            READ_OR_RETURN(liquid->GetFlagsStorage(), size);
        }
        return true;
    }