示例#1
0
文件: renderlib.cpp 项目: paud/d2x-xl
g3sCodes RotateVertexList (int nVertices, short* vertexIndexP)
{
	int			i;
	g3sPoint		*p;
	g3sCodes		cc = {0, 0xff};

for (i = 0; i < nVertices; i++) {
	p = RotateVertex (vertexIndexP [i]);
	cc.ccAnd &= p->p3_codes;
	cc.ccOr |= p->p3_codes;
	}
	return cc;
}
示例#2
0
bool Map::LoadV2(FILE *f) {
	uint32 data_size;
	if (fread(&data_size, sizeof(data_size), 1, f) != 1) {
		return false;
	}

	uint32 buffer_size;
	if (fread(&buffer_size, sizeof(buffer_size), 1, f) != 1) {
		return false;
	}

	std::vector<char> data;
	data.resize(data_size);
	if (fread(&data[0], data_size, 1, f) != 1) {
		return false;
	}

	std::vector<char> buffer;
	buffer.resize(buffer_size);
	uint32 v = InflateData(&data[0], data_size, &buffer[0], buffer_size);

	char *buf = &buffer[0];
	uint32 vert_count;
	uint32 ind_count;
	uint32 nc_vert_count;
	uint32 nc_ind_count;
	uint32 model_count;
	uint32 plac_count;
	uint32 plac_group_count;
	uint32 tile_count;
	uint32 quads_per_tile;
	float units_per_vertex;

	vert_count = *(uint32*)buf;
	buf += sizeof(uint32);

	ind_count = *(uint32*)buf;
	buf += sizeof(uint32);

	nc_vert_count = *(uint32*)buf;
	buf += sizeof(uint32);

	nc_ind_count = *(uint32*)buf;
	buf += sizeof(uint32);

	model_count = *(uint32*)buf;
	buf += sizeof(uint32);

	plac_count = *(uint32*)buf;
	buf += sizeof(uint32);

	plac_group_count = *(uint32*)buf;
	buf += sizeof(uint32);

	tile_count = *(uint32*)buf;
	buf += sizeof(uint32);

	quads_per_tile = *(uint32*)buf;
	buf += sizeof(uint32);

	units_per_vertex = *(float*)buf;
	buf += sizeof(float);

	std::vector<glm::vec3> verts;
	verts.reserve(vert_count);
	std::vector<uint32> indices;
	indices.reserve(ind_count);

	for (uint32 i = 0; i < vert_count; ++i) {
		float x;
		float y;
		float z;

		x = *(float*)buf;
		buf += sizeof(float);

		y = *(float*)buf;
		buf += sizeof(float);

		z = *(float*)buf;
		buf += sizeof(float);

		verts.emplace_back(x, y, z);
	}

	for (uint32 i = 0; i < ind_count; ++i) {
		indices.emplace_back(*(uint32 *)buf);
		buf += sizeof(uint32);
	}

	for (uint32 i = 0; i < nc_vert_count; ++i) {
		buf += sizeof(float) * 3;
	}

	for (uint32 i = 0; i < nc_ind_count; ++i) {
		buf += sizeof(uint32);
	}

	std::map<std::string, std::unique_ptr<ModelEntry>> models;
	for (uint32 i = 0; i < model_count; ++i) {
		std::unique_ptr<ModelEntry> me(new ModelEntry);
		std::string name = buf;
		buf += name.length() + 1;

		uint32 vert_count = *(uint32*)buf;
		buf += sizeof(uint32);

		uint32 poly_count = *(uint32*)buf;
		buf += sizeof(uint32);

		me->verts.reserve(vert_count);
		for (uint32 j = 0; j < vert_count; ++j) {
			float x = *(float*)buf;
			buf += sizeof(float);
			float y = *(float*)buf;
			buf += sizeof(float);
			float z = *(float*)buf;
			buf += sizeof(float);

			me->verts.emplace_back(x, y, z);
		}

		me->polys.reserve(poly_count);
		for (uint32 j = 0; j < poly_count; ++j) {
			uint32 v1 = *(uint32*)buf;
			buf += sizeof(uint32);
			uint32 v2 = *(uint32*)buf;
			buf += sizeof(uint32);
			uint32 v3 = *(uint32*)buf;
			buf += sizeof(uint32);
			uint8 vis = *(uint8*)buf;
			buf += sizeof(uint8);

			ModelEntry::Poly p;
			p.v1 = v1;
			p.v2 = v2;
			p.v3 = v3;
			p.vis = vis;
			me->polys.push_back(p);
		}

		models[name] = std::move(me);
	}

	for (uint32 i = 0; i < plac_count; ++i) {
		std::string name = buf;
		buf += name.length() + 1;

		float x = *(float*)buf;
		buf += sizeof(float);
		float y = *(float*)buf;
		buf += sizeof(float);
		float z = *(float*)buf;
		buf += sizeof(float);

		float x_rot = *(float*)buf;
		buf += sizeof(float);
		float y_rot = *(float*)buf;
		buf += sizeof(float);
		float z_rot = *(float*)buf;
		buf += sizeof(float);

		float x_scale = *(float*)buf;
		buf += sizeof(float);
		float y_scale = *(float*)buf;
		buf += sizeof(float);
		float z_scale = *(float*)buf;
		buf += sizeof(float);

		if (models.count(name) == 0)
			continue;

		auto &model = models[name];
		auto &mod_polys = model->polys;
		auto &mod_verts = model->verts;
		for (uint32 j = 0; j < mod_polys.size(); ++j) {
			auto &current_poly = mod_polys[j];
			if (current_poly.vis == 0)
				continue;
			auto v1 = mod_verts[current_poly.v1];
			auto v2 = mod_verts[current_poly.v2];
			auto v3 = mod_verts[current_poly.v3];

			RotateVertex(v1, x_rot, y_rot, z_rot);
			RotateVertex(v2, x_rot, y_rot, z_rot);
			RotateVertex(v3, x_rot, y_rot, z_rot);

			ScaleVertex(v1, x_scale, y_scale, z_scale);
			ScaleVertex(v2, x_scale, y_scale, z_scale);
			ScaleVertex(v3, x_scale, y_scale, z_scale);

			TranslateVertex(v1, x, y, z);
			TranslateVertex(v2, x, y, z);
			TranslateVertex(v3, x, y, z);

			verts.emplace_back(v1.y, v1.x, v1.z); // x/y swapped
			verts.emplace_back(v2.y, v2.x, v2.z);
			verts.emplace_back(v3.y, v3.x, v3.z);

			indices.emplace_back((uint32)verts.size() - 3);
			indices.emplace_back((uint32)verts.size() - 2);
			indices.emplace_back((uint32)verts.size() - 1);
		}
	}

	for (uint32 i = 0; i < plac_group_count; ++i) {
		float x = *(float*)buf;
		buf += sizeof(float);
		float y = *(float*)buf;
		buf += sizeof(float);
		float z = *(float*)buf;
		buf += sizeof(float);

		float x_rot = *(float*)buf;
		buf += sizeof(float);
		float y_rot = *(float*)buf;
		buf += sizeof(float);
		float z_rot = *(float*)buf;
		buf += sizeof(float);

		float x_scale = *(float*)buf;
		buf += sizeof(float);
		float y_scale = *(float*)buf;
		buf += sizeof(float);
		float z_scale = *(float*)buf;
		buf += sizeof(float);

		float x_tile = *(float*)buf;
		buf += sizeof(float);
		float y_tile = *(float*)buf;
		buf += sizeof(float);
		float z_tile = *(float*)buf;
		buf += sizeof(float);

		uint32 p_count = *(uint32*)buf;
		buf += sizeof(uint32);

		for (uint32 j = 0; j < p_count; ++j) {
			std::string name = buf;
			buf += name.length() + 1;

			float p_x = *(float*)buf;
			buf += sizeof(float);
			float p_y = *(float*)buf;
			buf += sizeof(float);
			float p_z = *(float*)buf;
			buf += sizeof(float);

			float p_x_rot = *(float*)buf * 3.14159f / 180;
			buf += sizeof(float);
			float p_y_rot = *(float*)buf * 3.14159f / 180;
			buf += sizeof(float);
			float p_z_rot = *(float*)buf * 3.14159f / 180;
			buf += sizeof(float);

			float p_x_scale = *(float*)buf;
			buf += sizeof(float);
			float p_y_scale = *(float*)buf;
			buf += sizeof(float);
			float p_z_scale = *(float*)buf;
			buf += sizeof(float);

			if (models.count(name) == 0)
				continue;

			auto &model = models[name];

			for (size_t k = 0; k < model->polys.size(); ++k) {
				auto &poly = model->polys[k];
				if (poly.vis == 0)
					continue;
				glm::vec3 v1, v2, v3;

				v1 = model->verts[poly.v1];
				v2 = model->verts[poly.v2];
				v3 = model->verts[poly.v3];

				ScaleVertex(v1, p_x_scale, p_y_scale, p_z_scale);
				ScaleVertex(v2, p_x_scale, p_y_scale, p_z_scale);
				ScaleVertex(v3, p_x_scale, p_y_scale, p_z_scale);

				TranslateVertex(v1, p_x, p_y, p_z);
				TranslateVertex(v2, p_x, p_y, p_z);
				TranslateVertex(v3, p_x, p_y, p_z);

				RotateVertex(v1, x_rot * 3.14159f / 180.0f, 0, 0);
				RotateVertex(v2, x_rot * 3.14159f / 180.0f, 0, 0);
				RotateVertex(v3, x_rot * 3.14159f / 180.0f, 0, 0);

				RotateVertex(v1, 0, y_rot * 3.14159f / 180.0f, 0);
				RotateVertex(v2, 0, y_rot * 3.14159f / 180.0f, 0);
				RotateVertex(v3, 0, y_rot * 3.14159f / 180.0f, 0);

				glm::vec3 correction(p_x, p_y, p_z);

				RotateVertex(correction, x_rot * 3.14159f / 180.0f, 0, 0);

				TranslateVertex(v1, -correction.x, -correction.y, -correction.z);
				TranslateVertex(v2, -correction.x, -correction.y, -correction.z);
				TranslateVertex(v3, -correction.x, -correction.y, -correction.z);

				RotateVertex(v1, p_x_rot, 0, 0);
				RotateVertex(v2, p_x_rot, 0, 0);
				RotateVertex(v3, p_x_rot, 0, 0);

				RotateVertex(v1, 0, -p_y_rot, 0);
				RotateVertex(v2, 0, -p_y_rot, 0);
				RotateVertex(v3, 0, -p_y_rot, 0);

				RotateVertex(v1, 0, 0, p_z_rot);
				RotateVertex(v2, 0, 0, p_z_rot);
				RotateVertex(v3, 0, 0, p_z_rot);

				TranslateVertex(v1, correction.x, correction.y, correction.z);
				TranslateVertex(v2, correction.x, correction.y, correction.z);
				TranslateVertex(v3, correction.x, correction.y, correction.z);

				RotateVertex(v1, 0, 0, z_rot * 3.14159f / 180.0f);
				RotateVertex(v2, 0, 0, z_rot * 3.14159f / 180.0f);
				RotateVertex(v3, 0, 0, z_rot * 3.14159f / 180.0f);

				ScaleVertex(v1, x_scale, y_scale, z_scale);
				ScaleVertex(v2, x_scale, y_scale, z_scale);
				ScaleVertex(v3, x_scale, y_scale, z_scale);

				TranslateVertex(v1, x_tile, y_tile, z_tile);
				TranslateVertex(v2, x_tile, y_tile, z_tile);
				TranslateVertex(v3, x_tile, y_tile, z_tile);

				TranslateVertex(v1, x, y, z);
				TranslateVertex(v2, x, y, z);
				TranslateVertex(v3, x, y, z);

				verts.emplace_back(v1.y, v1.x, v1.z); // x/y swapped
				verts.emplace_back(v2.y, v2.x, v2.z);
				verts.emplace_back(v3.y, v3.x, v3.z);

				indices.emplace_back((uint32)verts.size() - 3);
				indices.emplace_back((uint32)verts.size() - 2);
				indices.emplace_back((uint32)verts.size() - 1);
			}
		}
	}

	uint32 ter_quad_count = (quads_per_tile * quads_per_tile);
	uint32 ter_vert_count = ((quads_per_tile + 1) * (quads_per_tile + 1));
	std::vector<uint8> flags;
	std::vector<float> floats;
	flags.resize(ter_quad_count);
	floats.resize(ter_vert_count);
	for (uint32 i = 0; i < tile_count; ++i) {
		bool flat;
		flat = *(bool*)buf;
		buf += sizeof(bool);

		float x;
		x = *(float*)buf;
		buf += sizeof(float);

		float y;
		y = *(float*)buf;
		buf += sizeof(float);

		if (flat) {
			float z;
			z = *(float*)buf;
			buf += sizeof(float);

			float QuadVertex1X = x;
			float QuadVertex1Y = y;
			float QuadVertex1Z = z;

			float QuadVertex2X = QuadVertex1X + (quads_per_tile * units_per_vertex);
			float QuadVertex2Y = QuadVertex1Y;
			float QuadVertex2Z = QuadVertex1Z;

			float QuadVertex3X = QuadVertex2X;
			float QuadVertex3Y = QuadVertex1Y + (quads_per_tile * units_per_vertex);
			float QuadVertex3Z = QuadVertex1Z;

			float QuadVertex4X = QuadVertex1X;
			float QuadVertex4Y = QuadVertex3Y;
			float QuadVertex4Z = QuadVertex1Z;

			uint32 current_vert = (uint32)verts.size() + 3;
			verts.emplace_back(QuadVertex1X, QuadVertex1Y, QuadVertex1Z);
			verts.emplace_back(QuadVertex2X, QuadVertex2Y, QuadVertex2Z);
			verts.emplace_back(QuadVertex3X, QuadVertex3Y, QuadVertex3Z);
			verts.emplace_back(QuadVertex4X, QuadVertex4Y, QuadVertex4Z);

			indices.emplace_back(current_vert);
			indices.emplace_back(current_vert - 2);
			indices.emplace_back(current_vert - 1);

			indices.emplace_back(current_vert);
			indices.emplace_back(current_vert - 3);
			indices.emplace_back(current_vert - 2);
		}
		else {
			//read flags
			for (uint32 j = 0; j < ter_quad_count; ++j) {
				uint8 f;
				f = *(uint8*)buf;
				buf += sizeof(uint8);

				flags[j] = f;
			}

			//read floats
			for (uint32 j = 0; j < ter_vert_count; ++j) {
				float f;
				f = *(float*)buf;
				buf += sizeof(float);

				floats[j] = f;
			}

			int row_number = -1;
			std::map<std::tuple<float, float, float>, uint32> cur_verts;
			for (uint32 quad = 0; quad < ter_quad_count; ++quad) {
				if ((quad % quads_per_tile) == 0) {
					++row_number;
				}

				if (flags[quad] & 0x01)
					continue;

				float QuadVertex1X = x + (row_number * units_per_vertex);
				float QuadVertex1Y = y + (quad % quads_per_tile) * units_per_vertex;
				float QuadVertex1Z = floats[quad + row_number];

				float QuadVertex2X = QuadVertex1X + units_per_vertex;
				float QuadVertex2Y = QuadVertex1Y;
				float QuadVertex2Z = floats[quad + row_number + quads_per_tile + 1];

				float QuadVertex3X = QuadVertex1X + units_per_vertex;
				float QuadVertex3Y = QuadVertex1Y + units_per_vertex;
				float QuadVertex3Z = floats[quad + row_number + quads_per_tile + 2];

				float QuadVertex4X = QuadVertex1X;
				float QuadVertex4Y = QuadVertex1Y + units_per_vertex;
				float QuadVertex4Z = floats[quad + row_number + 1];

				uint32 i1, i2, i3, i4;
				std::tuple<float, float, float> t = std::make_tuple(QuadVertex1X, QuadVertex1Y, QuadVertex1Z);
				auto iter = cur_verts.find(t);
				if (iter != cur_verts.end()) {
					i1 = iter->second;
				}
				else {
					i1 = (uint32)verts.size();
					verts.emplace_back(QuadVertex1X, QuadVertex1Y, QuadVertex1Z);
					cur_verts[std::make_tuple(QuadVertex1X, QuadVertex1Y, QuadVertex1Z)] = i1;
				}

				t = std::make_tuple(QuadVertex2X, QuadVertex2Y, QuadVertex2Z);
				iter = cur_verts.find(t);
				if (iter != cur_verts.end()) {
					i2 = iter->second;
				}
				else {
					i2 = (uint32)verts.size();
					verts.emplace_back(QuadVertex2X, QuadVertex2Y, QuadVertex2Z);
					cur_verts[std::make_tuple(QuadVertex2X, QuadVertex2Y, QuadVertex2Z)] = i2;
				}

				t = std::make_tuple(QuadVertex3X, QuadVertex3Y, QuadVertex3Z);
				iter = cur_verts.find(t);
				if (iter != cur_verts.end()) {
					i3 = iter->second;
				}
				else {
					i3 = (uint32)verts.size();
					verts.emplace_back(QuadVertex3X, QuadVertex3Y, QuadVertex3Z);
					cur_verts[std::make_tuple(QuadVertex3X, QuadVertex3Y, QuadVertex3Z)] = i3;
				}

				t = std::make_tuple(QuadVertex4X, QuadVertex4Y, QuadVertex4Z);
				iter = cur_verts.find(t);
				if (iter != cur_verts.end()) {
					i4 = iter->second;
				}
				else {
					i4 = (uint32)verts.size();
					verts.emplace_back(QuadVertex4X, QuadVertex4Y, QuadVertex4Z);
					cur_verts[std::make_tuple(QuadVertex4X, QuadVertex4Y, QuadVertex4Z)] = i4;
				}

				indices.emplace_back(i4);
				indices.emplace_back(i2);
				indices.emplace_back(i3);

				indices.emplace_back(i4);
				indices.emplace_back(i1);
				indices.emplace_back(i2);
			}
		}
	}

	uint32 face_count = indices.size() / 3;

	if (imp) {
		imp->rm->release();
		imp->rm = nullptr;
	}
	else {
		imp = new impl;
	}

	imp->rm = createRaycastMesh((RmUint32)verts.size(), (const RmReal*)&verts[0], face_count, &indices[0]);

	if (!imp->rm) {
		delete imp;
		imp = nullptr;
		return false;
	}

	return true;
}
示例#3
0
文件: map.cpp 项目: brainiac/MQ2Nav
void Map::TraverseBone(std::shared_ptr<EQEmu::S3D::SkeletonTrack::Bone> bone, glm::vec3 parent_trans, glm::vec3 parent_rot, glm::vec3 parent_scale)
{
	float offset_x = 0.0f;
	float offset_y = 0.0f;
	float offset_z = 0.0f;

	float rot_x = 0.0f;
	float rot_y = 0.0f;
	float rot_z = 0.0f;

	float scale_x = parent_scale.x;
	float scale_y = parent_scale.y;
	float scale_z = parent_scale.z;

	if(bone->orientation) {
		if (bone->orientation->shift_denom != 0) {
			offset_x = (float)bone->orientation->shift_x_num / (float)bone->orientation->shift_denom;
			offset_y = (float)bone->orientation->shift_y_num / (float)bone->orientation->shift_denom;
			offset_z = (float)bone->orientation->shift_z_num / (float)bone->orientation->shift_denom;
		}

		if(bone->orientation->rotate_denom != 0) {
			rot_x = (float)bone->orientation->rotate_x_num / (float)bone->orientation->rotate_denom;
			rot_y = (float)bone->orientation->rotate_y_num / (float)bone->orientation->rotate_denom;
			rot_z = (float)bone->orientation->rotate_z_num / (float)bone->orientation->rotate_denom;

			rot_x = rot_x * 3.14159f / 180.0f;
			rot_y = rot_y * 3.14159f / 180.0f;
			rot_z = rot_z * 3.14159f / 180.0f;
		}
	}

	glm::vec3 pos(offset_x, offset_y, offset_z);
	glm::vec3 rot(rot_x, rot_y, rot_z);

	RotateVertex(pos, parent_rot.x, parent_rot.y, parent_rot.z);
	pos += parent_trans;
	
	rot += parent_rot;

	if(bone->model) {
		auto &mod_polys = bone->model->GetPolygons();
		auto &mod_verts = bone->model->GetVertices();

		if (map_models.count(bone->model->GetName()) == 0) {
			map_models[bone->model->GetName()] = bone->model;
		}
		
		std::shared_ptr<EQEmu::Placeable> gen_plac(new EQEmu::Placeable());
		gen_plac->SetFileName(bone->model->GetName());
		gen_plac->SetLocation(pos.x, pos.y, pos.z);
		gen_plac->SetRotation(rot.x, rot.y, rot.z);
		gen_plac->SetScale(scale_x, scale_y, scale_z);
		map_placeables.push_back(gen_plac);

		eqLogMessage(LogTrace, "Adding placeable %s at (%f, %f, %f)",bone->model->GetName().c_str(), pos.x, pos.y, pos.z);
	}

	for(size_t i = 0; i < bone->children.size(); ++i) {
		TraverseBone(bone->children[i], pos, rot, parent_scale);
	}
}
示例#4
0
static inline void RotateVertex(glm::vec3& v, const glm::vec3& r)
{
	RotateVertex(v, r.x, r.y, r.z);
}
示例#5
0
bool MapGeometryLoader::load()
{
	uint32_t counter = 0;

	if (!Build())
	{
		return false;
	}

	// load terrain geometry
	if (terrain)
	{
		const auto& tiles = terrain->GetTiles();
		uint32_t quads_per_tile = terrain->GetQuadsPerTile();
		float units_per_vertex = terrain->GetUnitsPerVertex();
		uint32_t vert_count = ((quads_per_tile + 1) * (quads_per_tile + 1));
		uint32_t quad_count = (quads_per_tile * quads_per_tile);

		for (uint32_t i = 0; i < tiles.size(); ++i)
		{
			auto& tile = tiles[i];
			bool flat = tile->IsFlat();

			float x = tile->GetX();
			float y = tile->GetY();


			if (flat)
			{
				float z = tile->GetFloats()[0];

				// get x,y of corner point for this quad
				float dt = quads_per_tile * units_per_vertex;

				addVertex(x,      z, y);
				addVertex(x + dt, z, y);
				addVertex(x + dt, z, y + dt);
				addVertex(x,      z, y + dt);

				addTriangle(counter + 0, counter + 2, counter + 1);
				addTriangle(counter + 2, counter + 0, counter + 3);

				counter += 4;
			}
			else
			{
				auto& floats = tile->GetFloats();
				int row_number = -1;

				for (uint32_t quad = 0; quad < quad_count; ++quad)
				{
					if (quad % quads_per_tile == 0)
						++row_number;

					if (tile->GetFlags()[quad] & 0x01)
						continue;

					// get x,y of corner point for this quad
					float _x = x + (row_number * units_per_vertex);
					float _y = y + (quad % quads_per_tile) * units_per_vertex;
					float dt = units_per_vertex;

					float z1 = floats[quad + row_number];
					float z2 = floats[quad + row_number + quads_per_tile + 1];
					float z3 = floats[quad + row_number + quads_per_tile + 2];
					float z4 = floats[quad + row_number + 1];

					addVertex(_x,      z1, _y);
					addVertex(_x + dt, z2, _y);
					addVertex(_x + dt, z3, _y + dt);
					addVertex(_x,      z4, _y + dt);

					addTriangle(counter + 0, counter + 2, counter + 1);
					addTriangle(counter + 2, counter + 0, counter + 3);

					counter += 4;
				}
			}
		}
	}

	for (uint32_t index = 0; index < collide_indices.size(); index += 3, counter += 3)
	{
		uint32_t vert_index1 = collide_indices[index];
		const glm::vec3& vert1 = collide_verts[vert_index1];
		addVertex(vert1.x, vert1.z, vert1.y);

		uint32_t vert_index2 = collide_indices[index + 2];
		const glm::vec3& vert2 = collide_verts[vert_index2];
		addVertex(vert2.x, vert2.z, vert2.y);

		uint32_t vert_index3 = collide_indices[index + 1];
		const glm::vec3& vert3 = collide_verts[vert_index3];
		addVertex(vert3.x, vert3.z, vert3.y);

		addTriangle(counter, counter + 2, counter + 1);
	}

	// Load models
	for (auto iter : map_models)
	{
		std::string name = iter.first;
		std::shared_ptr<EQEmu::S3D::Geometry> model = iter.second;

		std::shared_ptr<ModelEntry> entry = std::make_shared<ModelEntry>();

		for (const auto& vert : model->GetVertices())
		{
			entry->verts.push_back(vert.pos);
		}

		for (const auto& poly : model->GetPolygons())
		{
			entry->polys.emplace_back(
				ModelEntry::Poly{ poly.verts[0], poly.verts[1], poly.verts[2], (poly.flags & 0x10) == 0 });
		}

		m_models.emplace(std::make_pair(std::move(name), std::move(entry)));
	}
	for (auto iter : map_eqg_models)
	{
		bool first = true;
		std::string name = iter.first;
		std::shared_ptr<EQEmu::EQG::Geometry> model = iter.second;
		std::shared_ptr<ModelEntry> entry = std::make_shared<ModelEntry>();

		for (const auto& vert : model->GetVertices())
		{
			entry->verts.push_back(vert.pos);
		}

		for (const auto& poly : model->GetPolygons())
		{
			// 0x10 = invisible
			// 0x01 = no collision
			entry->polys.emplace_back(
				ModelEntry::Poly{ poly.verts[0], poly.verts[1], poly.verts[2], (poly.flags & 0x11) == 0 });
		}

		m_models.emplace(std::make_pair(std::move(name), std::move(entry)));
	}

	auto AddTriangle = [&](const glm::vec3& v1, const glm::vec3& v2, const glm::vec3& v3)
	{
		addVertex(v1.y, v1.z, v1.x);
		addVertex(v2.y, v2.z, v2.x);
		addVertex(v3.y, v3.z, v3.x);

		addTriangle(counter, counter + 1, counter + 2);
		counter += 3;
	};

	for (const auto& obj : map_placeables)
	{
		const std::string& name = obj->GetFileName();

		auto modelIter = m_models.find(name);
		if (modelIter == m_models.end())
			continue;

		// some objects have a really low z, just ignore them.
		if (obj->GetZ() < -30000)
			continue;

		const auto& model = modelIter->second;
		for (const auto& poly : model->polys)
		{
			if (!poly.vis)
				continue;

			glm::vec3 v[3];
			for (int i = 0; i < 3; i++)
			{
				v[i] = model->verts[poly.v[i]];

				RotateVertex(v[i], GetRotation(obj));
				ScaleVertex(v[i], GetScale(obj));
				TranslateVertex(v[i], GetTranslation(obj));
			}

			AddTriangle(v[0], v[1], v[2]);
		}
	}

	for (const auto& group : map_group_placeables)
	{
		for (const auto& obj : group->GetPlaceables())
		{
			const std::string& name = obj->GetFileName();

			auto modelIter = m_models.find(name);
			if (modelIter == m_models.end())
				continue;

			const auto& model = modelIter->second;
			for (const auto& poly : model->polys)
			{
				if (!poly.vis)
					continue;

				glm::vec3 v_[3];
				for (int i = 0; i < 3; i++)
				{
					glm::vec3& v = v_[i];
					v = model->verts[poly.v[i]];

					ScaleVertex(v, GetScale(obj));
					TranslateVertex(v, GetTranslation(obj));

					RotateVertex(v, group->GetRotationX() * M_PI / 180, 0, 0);
					RotateVertex(v, 0, group->GetRotationY() * M_PI / 180, 0);

					glm::vec3 correction = GetTranslation(obj);

					RotateVertex(correction, group->GetRotationX() * M_PI / 180, 0, 0);

					TranslateVertex(v, -correction.x, -correction.y, -correction.z);

					RotateVertex(v, obj->GetRotateX() * M_PI / 180, 0, 0);
					RotateVertex(v, 0, -obj->GetRotateY() * M_PI / 180, 0);
					RotateVertex(v, 0, 0, obj->GetRotateZ() * M_PI / 180);

					TranslateVertex(v, correction.x, correction.y, correction.z);

					RotateVertex(v, 0, 0, group->GetRotationZ() * M_PI / 180);

					ScaleVertex(v, GetScale(group));

					TranslateVertex(v, group->GetTileX(), group->GetTileY(), group->GetTileZ());
					TranslateVertex(v, GetTranslation(group));
				}

				AddTriangle(v_[0], v_[1], v_[2]);
			}
		}
	}

	//const auto& non_collide_indices = map.GetNonCollideIndices();

	//for (uint32_t index = 0; index < non_collide_indices.size(); index += 3, counter += 3)
	//{
	//	uint32_t vert_index1 = non_collide_indices[index];
	//	const glm::vec3& vert1 = map.GetNonCollideVert(vert_index1);
	//	addVertex(vert1.x, vert1.z, vert1.y, vcap);

	//	uint32_t vert_index2 = non_collide_indices[index + 1];
	//	const glm::vec3& vert2 = map.GetNonCollideVert(vert_index2);
	//	addVertex(vert2.x, vert2.z, vert2.y, vcap);

	//	uint32_t vert_index3 = non_collide_indices[index + 2];
	//	const glm::vec3& vert3 = map.GetNonCollideVert(vert_index3);
	//	addVertex(vert3.x, vert3.z, vert3.y, vcap);

	//	addTriangle(counter, counter + 2, counter + 1, tcap);
	//}

	LoadDoors();

	//message = "Calculating Surface 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;
		}
	}

	return true;
}
示例#6
0
文件: modify.cpp 项目: paud/d2x-xl
void CMine::SpinSelection(double angle) 
{
	int nSegment = Current ()->segment;
	int nSide = Current ()->side;
	CDSegment *seg = Segments (nSegment);
	CDObject *obj;
	vms_vector center,opp_center;
	INT16 i;

#ifdef SPIN_RELATIVE
	double xspin,yspin,zspin;
	vms_vector rel [3];
#endif

/* calculate segment pointer */
switch (m_selectMode) {
	case POINT_MODE:
		ErrorMsg ("Cannot spin a point");
		break; /* can't spin a point */
	
	case LINE_MODE:
		ErrorMsg ("Cannot spin a line");
		break; /* line spinning not supported */
	
	case SIDE_MODE: // spin side around its center in the plane of the side
		// calculate center of current side
		theApp.SetModified (TRUE);
		center.x = center.y = center.z = 0;
		for (i = 0; i < 4; i++) {
			center.x += Vertices (seg->verts [side_vert [nSide][i]])->x;
			center.y += Vertices (seg->verts [side_vert [nSide][i]])->y;
			center.z += Vertices (seg->verts [side_vert [nSide][i]])->z;
			}
		center.x /= 4;
		center.y /= 4;
		center.z /= 4;
		// calculate orthogonal vector from lines which intersect point 0
		//       |x  y  z |
		// AxB = |ax ay az| = x(aybz-azby), y(azbx-axbz), z(axby-aybx)
		//       |bx by bz|
		struct vector {double x,y,z;};
		struct vector a,b,c;
		double length;
		INT16 vertnum1,vertnum2;

		vertnum1 = seg->verts [side_vert [nSide][0]];
		vertnum2 = seg->verts [side_vert [nSide][1]];
		a.x = (double)(Vertices (vertnum2)->x - Vertices (vertnum1)->x);
		a.y = (double)(Vertices (vertnum2)->y - Vertices (vertnum1)->y);
		a.z = (double)(Vertices (vertnum2)->z - Vertices (vertnum1)->z);
		vertnum1 = seg->verts [side_vert [nSide][0]];
		vertnum2 = seg->verts [side_vert [nSide][3]];
		b.x = (double)(Vertices (vertnum2)->x - Vertices (vertnum1)->x);
		b.y = (double)(Vertices (vertnum2)->y - Vertices (vertnum1)->y);
		b.z = (double)(Vertices (vertnum2)->z - Vertices (vertnum1)->z);
		c.x = a.y*b.z - a.z*b.y;
		c.y = a.z*b.x - a.x*b.z;
		c.z = a.x*b.y - a.y*b.x;
		// normalize the vector
		length = sqrt(c.x*c.x + c.y*c.y + c.z*c.z);
		c.x /= length;
		c.y /= length;
		c.z /= length;
		// set sign (since vert numbers for most sides don't follow right-handed convention)
		if (nSide!=1 && nSide!=5) {
			c.x = -c.x;
			c.y = -c.y;
			c.z = -c.z;
			}
		// set opposite center
		opp_center.x = center.x + (FIX)(0x10000L*c.x);
		opp_center.y = center.y + (FIX)(0x10000L*c.y);
		opp_center.z = center.z + (FIX)(0x10000L*c.z);
		/* rotate points around a line */
		for (i = 0; i < 4; i++) {
			RotateVertex(Vertices (seg->verts [side_vert [nSide][i]]),
			&center,&opp_center,angle);
			}
		break;


	case CUBE_MODE:	// spin cube around the center of the cube using screen's perspective
		// calculate center of current cube
		theApp.SetModified (TRUE);
		center.x = center.y = center.z = 0;
		for (i = 0; i < 8; i++) {
			center.x += Vertices (seg->verts [i])->x;
			center.y += Vertices (seg->verts [i])->y;
			center.z += Vertices (seg->verts [i])->z;
			}
		center.x /= 8;
		center.y /= 8;
		center.z /= 8;
		// calculate center of oppisite current side
		opp_center.x = opp_center.y = opp_center.z = 0;
		for (i = 0; i < 4; i++) {
			opp_center.x += Vertices (seg->verts [opp_side_vert [nSide][i]])->x;
			opp_center.y += Vertices (seg->verts [opp_side_vert [nSide][i]])->y;
			opp_center.z += Vertices (seg->verts [opp_side_vert [nSide][i]])->z;
			}
		opp_center.x /= 4;
		opp_center.y /= 4;
		opp_center.z /= 4;
		// rotate points about a point
		for (i = 0; i < 8; i++)
			RotateVertex(Vertices (seg->verts [i]),&center,&opp_center,angle);
		break;

	case OBJECT_MODE:	// spin object vector
		theApp.SetModified (TRUE);
		vms_matrix *orient;
		orient = (Current ()->object == GameInfo ().objects.count) ? &SecretOrient () : &CurrObj ()->orient;
		switch (nSide) {
			case 0:
				RotateVmsMatrix(orient,angle,'x');
				break;
			case 2:
				RotateVmsMatrix(orient,-angle,'x');
				break;
			case 1:
				RotateVmsMatrix(orient,-angle,'y');
				break;
			case 3:
				RotateVmsMatrix(orient,angle,'y');
				break;
			case 4:
				RotateVmsMatrix(orient,angle,'z');
				break;
			case 5:
				RotateVmsMatrix(orient,-angle,'z');
				break;
			}
#ifdef SPIN_RELATIVE
		// calculate angles to spin the side into the x-y plane
		// use points 0,1, and 2 of the side
		// make point0 the origin
		// and get coordinates of points 1 and 2 relative to point 0
		for (i=0;i<3;i++) {
			rel [i].x = vertices [seg->verts [side_vert [nSide][i]]].x - vertices [seg->verts [side_vert [nSide][0]]].x;
			rel [i].y = vertices [seg->verts [side_vert [nSide][i]]].y - vertices [seg->verts [side_vert [nSide][0]]].y;
			rel [i].z = vertices [seg->verts [side_vert [nSide][i]]].z - vertices [seg->verts [side_vert [nSide][0]]].z;
			}
		// calculate z-axis spin angle to rotate point1 so it lies in x-y plane
		zspin = (rel [1].x==rel [1].y) ? PI/4 : atan2(rel [1].y,rel [1].x);
		// spin all 3 points on z axis
		for (i=0;i<3;i++)
			RotateVmsVector(&rel [i],zspin,'z');
		// calculate y-axis spin angle to rotate point1 so it lies on x axis
		yspin = (rel [1].z==rel [1].x) ? PI/4 : atan2(rel [1].z,rel [1].x);
		// spin points 1 and 2 on y axis (don't need to spin point 0 since it is at 0,0,0)
		for (i=1;i<=2;i++)
			RotateVmsVector(&rel [i],yspin,'y');
		// calculate x-axis spin angle to rotate point2 so it lies in x-y plane
		xspin = (rel [2].z==rel [2].y) ? PI/4 : atan2(rel [2].z,rel [2].y);
		// spin points 2 on x axis (don't need to spin point 1 since it is on the x-axis
		RotateVmsVector(&rel [2],xspin,'x');
		RotateVmsMatrix(&obj->orient,zspin,'z');
		RotateVmsMatrix(&obj->orient,yspin,'y');
		RotateVmsMatrix(&obj->orient,xspin,'x');
		RotateVmsMatrix(&obj->orient,-xspin,'x');
		RotateVmsMatrix(&obj->orient,-yspin,'y');
		RotateVmsMatrix(&obj->orient,-zspin,'z');
#endif //SPIN_RELATIVE
		break;

	case BLOCK_MODE:
		theApp.SetModified (TRUE);
		// calculate center of current cube
		center.x = center.y = center.z = 0;
		for (i = 0; i < 8; i++) {
			center.x += Vertices (seg->verts [i])->x;
			center.y += Vertices (seg->verts [i])->y;
			center.z += Vertices (seg->verts [i])->z;
			}
		center.x /= 8;
		center.y /= 8;
		center.z /= 8;
		// calculate center of oppisite current side
		opp_center.x = opp_center.y = opp_center.z = 0;
		for (i = 0; i < 4; i++) {
			opp_center.x += Vertices (seg->verts [opp_side_vert [nSide][i]])->x;
			opp_center.y += Vertices (seg->verts [opp_side_vert [nSide][i]])->y;
			opp_center.z += Vertices (seg->verts [opp_side_vert [nSide][i]])->z;
			}
		opp_center.x /= 4;
		opp_center.y /= 4;
		opp_center.z /= 4;
		// rotate points about a point
		for (i=0;i<VertCount ();i++)
			if (*VertStatus (i) & MARKED_MASK)
				RotateVertex(Vertices (i),&center,&opp_center,angle);
		// rotate Objects () within marked cubes
		obj = Objects ();
		for (i = GameInfo ().objects.count; i; i--, obj++)
			if (Segments (obj->segnum)->wall_bitmask & MARKED_MASK)
				RotateVertex(&obj->pos, &center, &opp_center, angle);
		break;
	}
}
示例#7
0
文件: modify.cpp 项目: paud/d2x-xl
void CMine::RotateSelection (double angle, bool perpendicular) 
{
int nSegment = Current ()->segment;
int nSide = Current ()->side;
CDSegment *seg = Segments (nSegment);
vms_vector center,opp_center;
int i,pts [4];

switch (m_selectMode){
	case POINT_MODE:
	ErrorMsg("Cannot bend a point");
	break; /* can't spin a point */
	case LINE_MODE:
	ErrorMsg("Cannot bend a line");
	break; /* line spinning not supported */
	case SIDE_MODE:	// spin side around the opposite side
		theApp.SetModified (TRUE);
		theApp.LockUndo ();
		if (perpendicular) { // use lines 0 and 2
			pts [0] = 1;
			pts [1] = 2;
			pts [2] = 3;
			pts [3] = 0;
			} 
		else {             // use lines 1 and 3
			pts [0] = 0;
			pts [1] = 1;
			pts [2] = 2;
			pts [3] = 3;
			}
		// calculate center opp side line 0
		opp_center.x = (Vertices (seg->verts [opp_side_vert [nSide][pts [0]]])->x +
							 Vertices (seg->verts [opp_side_vert [nSide][pts [1]]])->x) / 2;
		opp_center.y = (Vertices (seg->verts [opp_side_vert [nSide][pts [0]]])->y +
							 Vertices (seg->verts [opp_side_vert [nSide][pts [1]]])->y) / 2;
		opp_center.z = (Vertices (seg->verts [opp_side_vert [nSide][pts [0]]])->z +
							 Vertices (seg->verts [opp_side_vert [nSide][pts [1]]])->z) / 2;
		// calculate center opp side line 2
		center.x = (Vertices (seg->verts [opp_side_vert [nSide][pts [2]]])->x +
						Vertices (seg->verts [opp_side_vert [nSide][pts [3]]])->x) / 2;
		center.y = (Vertices (seg->verts [opp_side_vert [nSide][pts [2]]])->y +
						Vertices (seg->verts [opp_side_vert [nSide][pts [3]]])->y) / 2;
		center.z = (Vertices (seg->verts [opp_side_vert [nSide][pts [2]]])->z +
						Vertices (seg->verts [opp_side_vert [nSide][pts [3]]])->z) / 2;
		// rotate points around a line
		for (i = 0; i < 4; i++)
			RotateVertex (Vertices (seg->verts [side_vert [nSide][i]]),
							  &center, &opp_center, angle);
		theApp.UnlockUndo ();	
		break;
	
	case CUBE_MODE:
		ErrorMsg("Cannot bend a cube");
		break; /* can't spin a point */
	
	case OBJECT_MODE:
		ErrorMsg("Cannot bend a object");
		break; /* can't spin a point */

	case BLOCK_MODE:
		ErrorMsg("Cannot bend a block");
		break; /* can't spin a point */
	}
}
示例#8
0
bool ZoneMap::LoadV2(FILE *f) {
	uint32_t data_size;
	if (fread(&data_size, sizeof(data_size), 1, f) != 1) {
		return false;
	}

	uint32_t buffer_size;
	if (fread(&buffer_size, sizeof(buffer_size), 1, f) != 1) {
		return false;
	}

	std::vector<char> data;
	data.resize(data_size);
	if (fread(&data[0], data_size, 1, f) != 1) {
		return false;
	}

	std::vector<char> buffer;
	buffer.resize(buffer_size);
	uint32_t v = InflateData(&data[0], data_size, &buffer[0], buffer_size);

	char *buf = &buffer[0];
	uint32_t vert_count;
	uint32_t ind_count;
	uint32_t nc_vert_count;
	uint32_t nc_ind_count;
	uint32_t model_count;
	uint32_t plac_count;
	uint32_t plac_group_count;
	uint32_t tile_count;
	uint32_t quads_per_tile;
	float units_per_vertex;

	vert_count = *(uint32_t*)buf;
	buf += sizeof(uint32_t);

	ind_count = *(uint32_t*)buf;
	buf += sizeof(uint32_t);

	nc_vert_count = *(uint32_t*)buf;
	buf += sizeof(uint32_t);

	nc_ind_count = *(uint32_t*)buf;
	buf += sizeof(uint32_t);

	model_count = *(uint32_t*)buf;
	buf += sizeof(uint32_t);

	plac_count = *(uint32_t*)buf;
	buf += sizeof(uint32_t);

	plac_group_count = *(uint32_t*)buf;
	buf += sizeof(uint32_t);

	tile_count = *(uint32_t*)buf;
	buf += sizeof(uint32_t);

	quads_per_tile = *(uint32_t*)buf;
	buf += sizeof(uint32_t);

	units_per_vertex = *(float*)buf;
	buf += sizeof(float);

	for (uint32_t i = 0; i < vert_count; ++i) {
		float x;
		float y;
		float z;

		x = *(float*)buf;
		buf += sizeof(float);

		y = *(float*)buf;
		buf += sizeof(float);

		z = *(float*)buf;
		buf += sizeof(float);

		glm::vec3 vert(x, y, z);

		imp->verts.push_back(vert);
	}

	for (uint32_t i = 0; i < ind_count; ++i) {
		uint32_t index;
		index = *(uint32_t*)buf;
		buf += sizeof(uint32_t);

		imp->inds.push_back(index);
	}

	for (uint32_t i = 0; i < nc_vert_count; ++i) {
		float x;
		float y;
		float z;

		x = *(float*)buf;
		buf += sizeof(float);

		y = *(float*)buf;
		buf += sizeof(float);

		z = *(float*)buf;
		buf += sizeof(float);

		glm::vec3 vert(x, y, z);

		imp->nc_verts.push_back(vert);
	}

	for (uint32_t i = 0; i < nc_ind_count; ++i) {
		uint32_t index;
		index = *(uint32_t*)buf;
		buf += sizeof(uint32_t);

		imp->nc_inds.push_back(index);
	}

	std::map<std::string, std::shared_ptr<ModelEntry>> models;
	for (uint32_t i = 0; i < model_count; ++i) {
		std::shared_ptr<ModelEntry> me(new ModelEntry);
		std::string name = buf;
		buf += name.length() + 1;

		uint32_t vert_count = *(uint32_t*)buf;
		buf += sizeof(uint32_t);

		uint32_t poly_count = *(uint32_t*)buf;
		buf += sizeof(uint32_t);

		me->verts.resize(vert_count);
		for (uint32_t j = 0; j < vert_count; ++j) {
			float x = *(float*)buf;
			buf += sizeof(float);
			float y = *(float*)buf;
			buf += sizeof(float);
			float z = *(float*)buf;
			buf += sizeof(float);

			me->verts[j] = glm::vec3(x, y, z);
		}

		me->polys.resize(poly_count);
		for (uint32_t j = 0; j < poly_count; ++j) {
			uint32_t v1 = *(uint32_t*)buf;
			buf += sizeof(uint32_t);
			uint32_t v2 = *(uint32_t*)buf;
			buf += sizeof(uint32_t);
			uint32_t v3 = *(uint32_t*)buf;
			buf += sizeof(uint32_t);
			uint8_t vis = *(uint8_t*)buf;
			buf += sizeof(uint8_t);

			ModelEntry::Poly p;
			p.v1 = v1;
			p.v2 = v2;
			p.v3 = v3;
			p.vis = vis;
			me->polys[j] = p;
		}

		models[name] = me;
	}

	for (uint32_t i = 0; i < plac_count; ++i) {
		std::string name = buf;
		buf += name.length() + 1;

		float x = *(float*)buf;
		buf += sizeof(float);
		float y = *(float*)buf;
		buf += sizeof(float);
		float z = *(float*)buf;
		buf += sizeof(float);

		float x_rot = *(float*)buf;
		buf += sizeof(float);
		float y_rot = *(float*)buf;
		buf += sizeof(float);
		float z_rot = *(float*)buf;
		buf += sizeof(float);

		float x_scale = *(float*)buf;
		buf += sizeof(float);
		float y_scale = *(float*)buf;
		buf += sizeof(float);
		float z_scale = *(float*)buf;
		buf += sizeof(float);

		if (models.count(name) == 0)
			continue;

		auto model = models[name];
		auto &mod_polys = model->polys;
		auto &mod_verts = model->verts;
		for (uint32_t j = 0; j < mod_polys.size(); ++j) {
			auto &current_poly = mod_polys[j];
			auto v1 = mod_verts[current_poly.v1];
			auto v2 = mod_verts[current_poly.v2];
			auto v3 = mod_verts[current_poly.v3];

			RotateVertex(v1, x_rot, y_rot, z_rot);
			RotateVertex(v2, x_rot, y_rot, z_rot);
			RotateVertex(v3, x_rot, y_rot, z_rot);

			ScaleVertex(v1, x_scale, y_scale, z_scale);
			ScaleVertex(v2, x_scale, y_scale, z_scale);
			ScaleVertex(v3, x_scale, y_scale, z_scale);

			TranslateVertex(v1, x, y, z);
			TranslateVertex(v2, x, y, z);
			TranslateVertex(v3, x, y, z);

			float t = v1.x;
			v1.x = v1.y;
			v1.y = t;

			t = v2.x;
			v2.x = v2.y;
			v2.y = t;

			t = v3.x;
			v3.x = v3.y;
			v3.y = t;

			if (current_poly.vis != 0) {
				imp->verts.push_back(v1);
				imp->verts.push_back(v2);
				imp->verts.push_back(v3);

				imp->inds.push_back((uint32_t)imp->verts.size() - 3);
				imp->inds.push_back((uint32_t)imp->verts.size() - 2);
				imp->inds.push_back((uint32_t)imp->verts.size() - 1);
			} else {
				imp->nc_verts.push_back(v1);
				imp->nc_verts.push_back(v2);
				imp->nc_verts.push_back(v3);

				imp->nc_inds.push_back((uint32_t)imp->nc_verts.size() - 3);
				imp->nc_inds.push_back((uint32_t)imp->nc_verts.size() - 2);
				imp->nc_inds.push_back((uint32_t)imp->nc_verts.size() - 1);
			}
		}
	}

	for (uint32_t i = 0; i < plac_group_count; ++i) {
		float x = *(float*)buf;
		buf += sizeof(float);
		float y = *(float*)buf;
		buf += sizeof(float);
		float z = *(float*)buf;
		buf += sizeof(float);

		float x_rot = *(float*)buf;
		buf += sizeof(float);
		float y_rot = *(float*)buf;
		buf += sizeof(float);
		float z_rot = *(float*)buf;
		buf += sizeof(float);

		float x_scale = *(float*)buf;
		buf += sizeof(float);
		float y_scale = *(float*)buf;
		buf += sizeof(float);
		float z_scale = *(float*)buf;
		buf += sizeof(float);

		float x_tile = *(float*)buf;
		buf += sizeof(float);
		float y_tile = *(float*)buf;
		buf += sizeof(float);
		float z_tile = *(float*)buf;
		buf += sizeof(float);

		uint32_t p_count = *(uint32_t*)buf;
		buf += sizeof(uint32_t);

		for (uint32_t j = 0; j < p_count; ++j) {
			std::string name = buf;
			buf += name.length() + 1;

			float p_x = *(float*)buf;
			buf += sizeof(float);
			float p_y = *(float*)buf;
			buf += sizeof(float);
			float p_z = *(float*)buf;
			buf += sizeof(float);

			float p_x_rot = *(float*)buf * 3.14159f / 180;
			buf += sizeof(float);
			float p_y_rot = *(float*)buf * 3.14159f / 180;
			buf += sizeof(float);
			float p_z_rot = *(float*)buf * 3.14159f / 180;
			buf += sizeof(float);

			float p_x_scale = *(float*)buf;
			buf += sizeof(float);
			float p_y_scale = *(float*)buf;
			buf += sizeof(float);
			float p_z_scale = *(float*)buf;
			buf += sizeof(float);

			if (models.count(name) == 0)
				continue;

			auto &model = models[name];

			for (size_t k = 0; k < model->polys.size(); ++k) {
				auto &poly = model->polys[k];
				glm::vec3 v1, v2, v3;

				v1 = model->verts[poly.v1];
				v2 = model->verts[poly.v2];
				v3 = model->verts[poly.v3];

				ScaleVertex(v1, p_x_scale, p_y_scale, p_z_scale);
				ScaleVertex(v2, p_x_scale, p_y_scale, p_z_scale);
				ScaleVertex(v3, p_x_scale, p_y_scale, p_z_scale);

				TranslateVertex(v1, p_x, p_y, p_z);
				TranslateVertex(v2, p_x, p_y, p_z);
				TranslateVertex(v3, p_x, p_y, p_z);

				RotateVertex(v1, x_rot * 3.14159f / 180.0f, 0, 0);
				RotateVertex(v2, x_rot * 3.14159f / 180.0f, 0, 0);
				RotateVertex(v3, x_rot * 3.14159f / 180.0f, 0, 0);

				RotateVertex(v1, 0, y_rot * 3.14159f / 180.0f, 0);
				RotateVertex(v2, 0, y_rot * 3.14159f / 180.0f, 0);
				RotateVertex(v3, 0, y_rot * 3.14159f / 180.0f, 0);

				glm::vec3 correction(p_x, p_y, p_z);

				RotateVertex(correction, x_rot * 3.14159f / 180.0f, 0, 0);

				TranslateVertex(v1, -correction.x, -correction.y, -correction.z);
				TranslateVertex(v2, -correction.x, -correction.y, -correction.z);
				TranslateVertex(v3, -correction.x, -correction.y, -correction.z);

				RotateVertex(v1, p_x_rot, 0, 0);
				RotateVertex(v2, p_x_rot, 0, 0);
				RotateVertex(v3, p_x_rot, 0, 0);

				RotateVertex(v1, 0, -p_y_rot, 0);
				RotateVertex(v2, 0, -p_y_rot, 0);
				RotateVertex(v3, 0, -p_y_rot, 0);

				RotateVertex(v1, 0, 0, p_z_rot);
				RotateVertex(v2, 0, 0, p_z_rot);
				RotateVertex(v3, 0, 0, p_z_rot);

				TranslateVertex(v1, correction.x, correction.y, correction.z);
				TranslateVertex(v2, correction.x, correction.y, correction.z);
				TranslateVertex(v3, correction.x, correction.y, correction.z);

				RotateVertex(v1, 0, 0, z_rot * 3.14159f / 180.0f);
				RotateVertex(v2, 0, 0, z_rot * 3.14159f / 180.0f);
				RotateVertex(v3, 0, 0, z_rot * 3.14159f / 180.0f);

				ScaleVertex(v1, x_scale, y_scale, z_scale);
				ScaleVertex(v2, x_scale, y_scale, z_scale);
				ScaleVertex(v3, x_scale, y_scale, z_scale);

				TranslateVertex(v1, x_tile, y_tile, z_tile);
				TranslateVertex(v2, x_tile, y_tile, z_tile);
				TranslateVertex(v3, x_tile, y_tile, z_tile);

				TranslateVertex(v1, x, y, z);
				TranslateVertex(v2, x, y, z);
				TranslateVertex(v3, x, y, z);

				float t = v1.x;
				v1.x = v1.y;
				v1.y = t;

				t = v2.x;
				v2.x = v2.y;
				v2.y = t;

				t = v3.x;
				v3.x = v3.y;
				v3.y = t;

				if (poly.vis != 0) {
					imp->verts.push_back(v1);
					imp->verts.push_back(v2);
					imp->verts.push_back(v3);

					imp->inds.push_back((uint32_t)imp->verts.size() - 3);
					imp->inds.push_back((uint32_t)imp->verts.size() - 2);
					imp->inds.push_back((uint32_t)imp->verts.size() - 1);
				} else {
					imp->nc_verts.push_back(v1);
					imp->nc_verts.push_back(v2);
					imp->nc_verts.push_back(v3);

					imp->nc_inds.push_back((uint32_t)imp->nc_verts.size() - 3);
					imp->nc_inds.push_back((uint32_t)imp->nc_verts.size() - 2);
					imp->nc_inds.push_back((uint32_t)imp->nc_verts.size() - 1);
				}
			}
		}
	}

	uint32_t ter_quad_count = (quads_per_tile * quads_per_tile);
	uint32_t ter_vert_count = ((quads_per_tile + 1) * (quads_per_tile + 1));
	std::vector<uint8_t> flags;
	std::vector<float> floats;
	flags.resize(ter_quad_count);
	floats.resize(ter_vert_count);
	for (uint32_t i = 0; i < tile_count; ++i) {
		bool flat;
		flat = *(bool*)buf;
		buf += sizeof(bool);

		float x;
		x = *(float*)buf;
		buf += sizeof(float);

		float y;
		y = *(float*)buf;
		buf += sizeof(float);

		if (flat) {
			float z;
			z = *(float*)buf;
			buf += sizeof(float);

			float QuadVertex1X = x;
			float QuadVertex1Y = y;
			float QuadVertex1Z = z;

			float QuadVertex2X = QuadVertex1X + (quads_per_tile * units_per_vertex);
			float QuadVertex2Y = QuadVertex1Y;
			float QuadVertex2Z = QuadVertex1Z;

			float QuadVertex3X = QuadVertex2X;
			float QuadVertex3Y = QuadVertex1Y + (quads_per_tile * units_per_vertex);
			float QuadVertex3Z = QuadVertex1Z;

			float QuadVertex4X = QuadVertex1X;
			float QuadVertex4Y = QuadVertex3Y;
			float QuadVertex4Z = QuadVertex1Z;

			uint32_t current_vert = (uint32_t)imp->verts.size() + 3;
			imp->verts.push_back(glm::vec3(QuadVertex1X, QuadVertex1Y, QuadVertex1Z));
			imp->verts.push_back(glm::vec3(QuadVertex2X, QuadVertex2Y, QuadVertex2Z));
			imp->verts.push_back(glm::vec3(QuadVertex3X, QuadVertex3Y, QuadVertex3Z));
			imp->verts.push_back(glm::vec3(QuadVertex4X, QuadVertex4Y, QuadVertex4Z));

			imp->inds.push_back(current_vert - 0);
			imp->inds.push_back(current_vert - 1);
			imp->inds.push_back(current_vert - 2);

			imp->inds.push_back(current_vert - 2);
			imp->inds.push_back(current_vert - 3);
			imp->inds.push_back(current_vert - 0);
		}
		else {
			//read flags
			for (uint32_t j = 0; j < ter_quad_count; ++j) {
				uint8_t f;
				f = *(uint8_t*)buf;
				buf += sizeof(uint8_t);

				flags[j] = f;
			}

			//read floats
			for (uint32_t j = 0; j < ter_vert_count; ++j) {
				float f;
				f = *(float*)buf;
				buf += sizeof(float);

				floats[j] = f;
			}

			int row_number = -1;
			std::map<std::tuple<float, float, float>, uint32_t> cur_verts;
			for (uint32_t quad = 0; quad < ter_quad_count; ++quad) {
				if ((quad % quads_per_tile) == 0) {
					++row_number;
				}

				if (flags[quad] & 0x01)
					continue;

				float QuadVertex1X = x + (row_number * units_per_vertex);
				float QuadVertex1Y = y + (quad % quads_per_tile) * units_per_vertex;
				float QuadVertex1Z = floats[quad + row_number];

				float QuadVertex2X = QuadVertex1X + units_per_vertex;
				float QuadVertex2Y = QuadVertex1Y;
				float QuadVertex2Z = floats[quad + row_number + quads_per_tile + 1];

				float QuadVertex3X = QuadVertex1X + units_per_vertex;
				float QuadVertex3Y = QuadVertex1Y + units_per_vertex;
				float QuadVertex3Z = floats[quad + row_number + quads_per_tile + 2];

				float QuadVertex4X = QuadVertex1X;
				float QuadVertex4Y = QuadVertex1Y + units_per_vertex;
				float QuadVertex4Z = floats[quad + row_number + 1];

				uint32_t i1, i2, i3, i4;
				std::tuple<float, float, float> t = std::make_tuple(QuadVertex1X, QuadVertex1Y, QuadVertex1Z);
				auto iter = cur_verts.find(t);
				if (iter != cur_verts.end()) {
					i1 = iter->second;
				}
				else {
					i1 = (uint32_t)imp->verts.size();
					imp->verts.push_back(glm::vec3(QuadVertex1X, QuadVertex1Y, QuadVertex1Z));
					cur_verts[std::make_tuple(QuadVertex1X, QuadVertex1Y, QuadVertex1Z)] = i1;
				}

				t = std::make_tuple(QuadVertex2X, QuadVertex2Y, QuadVertex2Z);
				iter = cur_verts.find(t);
				if (iter != cur_verts.end()) {
					i2 = iter->second;
				}
				else {
					i2 = (uint32_t)imp->verts.size();
					imp->verts.push_back(glm::vec3(QuadVertex2X, QuadVertex2Y, QuadVertex2Z));
					cur_verts[std::make_tuple(QuadVertex2X, QuadVertex2Y, QuadVertex2Z)] = i2;
				}

				t = std::make_tuple(QuadVertex3X, QuadVertex3Y, QuadVertex3Z);
				iter = cur_verts.find(t);
				if (iter != cur_verts.end()) {
					i3 = iter->second;
				}
				else {
					i3 = (uint32_t)imp->verts.size();
					imp->verts.push_back(glm::vec3(QuadVertex3X, QuadVertex3Y, QuadVertex3Z));
					cur_verts[std::make_tuple(QuadVertex3X, QuadVertex3Y, QuadVertex3Z)] = i3;
				}

				t = std::make_tuple(QuadVertex4X, QuadVertex4Y, QuadVertex4Z);
				iter = cur_verts.find(t);
				if (iter != cur_verts.end()) {
					i4 = iter->second;
				}
				else {
					i4 = (uint32_t)imp->verts.size();
					imp->verts.push_back(glm::vec3(QuadVertex4X, QuadVertex4Y, QuadVertex4Z));
					cur_verts[std::make_tuple(QuadVertex4X, QuadVertex4Y, QuadVertex4Z)] = i4;
				}

				imp->inds.push_back(i4);
				imp->inds.push_back(i3);
				imp->inds.push_back(i2);

				imp->inds.push_back(i2);
				imp->inds.push_back(i1);
				imp->inds.push_back(i4);
			}
		}
	}

	float t;
	for(auto &v : imp->verts) {
		t = v.y;
		v.y = v.z;
		v.z = t;
	}

	for(auto &vert : imp->verts) {
		if(vert.x < imp->min.x) {
			imp->min.x = vert.x;
		}

		if(vert.y < imp->min.y && vert.y > -15000) {
			imp->min.y = vert.y;
		}

		if(vert.z < imp->min.z) {
			imp->min.z = vert.z;
		}

		if(vert.x > imp->max.x) {
			imp->max.x = vert.x;
		}

		if(vert.y > imp->max.y) {
			imp->max.y = vert.y;
		}

		if(vert.z > imp->max.z) {
			imp->max.z = vert.z;
		}
	}

	for(auto &v : imp->nc_verts) {
		t = v.y;
		v.y = v.z;
		v.z = t;
	}

	for(auto &vert : imp->nc_verts) {
		if(vert.x < imp->nc_min.x) {
			imp->nc_min.x = vert.x;
		}

		if(vert.y < imp->nc_min.y) {
			imp->nc_min.y = vert.y;
		}

		if(vert.z < imp->nc_min.z) {
			imp->nc_min.z = vert.z;
		}

		if(vert.x > imp->nc_max.x) {
			imp->nc_max.x = vert.x;
		}

		if(vert.y > imp->nc_max.y) {
			imp->nc_max.y = vert.y;
		}

		if(vert.z > imp->nc_max.z) {
			imp->nc_max.z = vert.z;
		}
	}

	return true;
}