void DoorsDebugUI::Render()
{
if (!m_showDoorsUI)
		return;

	ImGui::SetNextWindowSize(ImVec2(500, 120), ImGuiSetCond_FirstUseEver);
	if (!ImGui::Begin("EQ Doors", &m_showDoorsUI))
		return;

	PDOORTABLE pDoorTable = (PDOORTABLE)pSwitchMgr;

	ImGui::Text("%d door objects", pDoorTable->NumEntries);

	ImGui::Columns(6, "doorcolumns");
	ImGui::Separator();

	auto header = [this](const char* name, int id) {
		if (ImGui::Selectable(name, m_doorsSortColumn == id)) {
			m_sortReverse = (m_doorsSortColumn == id) ? !m_sortReverse : false;
			m_doorsSortColumn = id;
		}
		ImGui::NextColumn();
	};

	header("ID", Sort_ID);
	header("Name", Sort_Name);
	header("Type", Sort_Type);
	header("State", Sort_State);
	header("Distance", Sort_Distance);
	/* buttons */ ImGui::NextColumn();

	ImGui::Separator();

	std::vector<PDOOR> doors(pDoorTable->NumEntries);

	for (DWORD count = 0; count < pDoorTable->NumEntries; count++)
	{
		doors[count] = pDoorTable->pDoor[count];
	}

	std::sort(doors.begin(), doors.end(),
		[this](PDOOR a, PDOOR b) -> bool
	{
		bool less = false;
		if (m_doorsSortColumn == Sort_ID)
			less = a->ID < b->ID;
		else if (m_doorsSortColumn == Sort_Name)
			less = strcmp(a->Name, b->Name) < 0;
		else if (m_doorsSortColumn == Sort_Type)
			less = a->Type < b->Type;
		else if (m_doorsSortColumn == Sort_State)
			less = a->State < b->State;
		else if (m_doorsSortColumn == Sort_Distance)
			less = GetDistance(a) < GetDistance(b);
		
		return less;
	});

	if (m_sortReverse)
		std::reverse(doors.begin(), doors.end());

	for (auto iter = doors.begin(); iter != doors.end(); ++iter)
	{
		PDOOR door = *iter;

		ImGui::PushID(door->ID);

		bool targetted = (m_lastDoorTargetId == door->ID);
		if (targetted)
			ImGui::PushStyleColor(ImGuiCol_Text, ImColor(0, 255, 0));

		ImGui::Text("%d", door->ID); ImGui::NextColumn();

		if (ImGui::Selectable(door->Name, targetted))
		{
			CHAR temp[256];
			sprintf_s(temp, "/doortarget id %d", door->ID);

			// would be nice if there was an easier way to do this.
			EzCommand(temp);
		}
		ImGui::NextColumn();
		ImGui::Text("%d", door->Type); ImGui::NextColumn();
		ImGui::Text("%d", door->State); ImGui::NextColumn();
		ImGui::Text("%.2f", GetDistance(door)); ImGui::NextColumn();

		if (targetted)
			ImGui::PopStyleColor();

		if (ImGui::Button("Click"))
			ClickDoor(door);

		if (targetted)
		{
			ImGui::SameLine();
			ImGui::Text("<Target>");
		}

		if (IsSwitchStationary(door))
		{
			ImGui::SameLine();
			ImGui::Text("*stationary*");
		}

		ImGui::NextColumn();

		ImGui::PopID();
	}

	ImGui::Separator();
	ImGui::Columns(1);
	ImGui::Separator();

	ImGui::End();
}
Example #2
0
void MapGeometryLoader::LoadDoors()
{
	//
	// Load the door data
	//
	std::string filename = m_meshPath + "\\MQ2Nav\\" + m_zoneName + "_doors.json";

	boost::system::error_code ec;
	if (!boost::filesystem::is_regular_file(filename, ec))
		return;

	std::stringstream ss;
	std::ifstream ifs;

	ifs.open(filename.c_str());
	ss << ifs.rdbuf();
	ifs.close();

	rapidjson::Document document;

	if (document.Parse<0>(ss.str().c_str()).HasParseError())
		return;
	if (!document.IsArray())
		return;

	std::vector<DoorParams> doors;
	m_hasDynamicObjects = true;

	for (auto iter = document.Begin(); iter != document.End(); ++iter)
	{
		if (!iter->IsObject())
			return;

		DoorParams params;
		params.id = (*iter)["ID"].GetInt();
		params.name = (*iter)["Name"].GetString();
		params.type = (*iter)["Type"].GetInt();
		params.scale = (*iter)["Scale"].GetDouble();

		// only add stationary objects
		if (!IsSwitchStationary(params.type))
			continue;

		const auto& t = (*iter)["Transform"];
		for (int i = 0; i < 4; i++)
		{
			for (int j = 0; j < 4; j++)
			{
				params.transform[i][j] = t[i][j].GetDouble();
			}
		}

		doors.push_back(params);
	}

	if (doors.empty()) {
		m_doorsLoaded = true;
		return;
	}

	//
	// Load the models for that door data
	//

	ZoneData zoneData(m_eqPath, m_zoneName);

	if (!zoneData.IsLoaded())
		return;

	uint32_t counter = m_vertCount;

	auto AddTriangle = [&](const glm::mat4x4& matrix, const glm::vec3& v1_, const glm::vec3& v2_, const glm::vec3& v3_)
	{
		glm::vec4 v1 = matrix * glm::vec4(v1_.x, v1_.y, v1_.z, 1.0);
		glm::vec4 v2 = matrix * glm::vec4(v2_.x, v2_.y, v2_.z, 1.0);
		glm::vec4 v3 = matrix * glm::vec4(v3_.x, v3_.y, v3_.z, 1.0);

		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;
	};

	// generic lambda for both old and new model types
	auto addModel = [&](const glm::mat4x4& matrix, float scale, auto modelPtr)
	{
		auto verts = modelPtr->GetVertices();
		auto polys = modelPtr->GetPolygons();

		for (auto iter = polys.begin(); iter != polys.end(); ++iter)
		{
			if (iter->flags & 0x11)
				continue;

			auto& polygon = *iter;
			AddTriangle(matrix,
				scale * verts[polygon.verts[0]].pos,
				scale * verts[polygon.verts[1]].pos,
				scale * verts[polygon.verts[2]].pos);
		}

		++m_dynamicObjects;
	};

	for (auto iter = doors.begin(); iter != doors.end(); ++iter)
	{
		auto& params = *iter;

		if (std::shared_ptr<ModelInfo> mi = zoneData.GetModelInfo(params.name))
		{
			glm::mat4x4 matrix = params.transform;

			if (mi->oldModel)
			{
				addModel(matrix, params.scale, mi->oldModel);
			}
			if (mi->newModel)
			{
				addModel(matrix, params.scale, mi->newModel);
			}
		}
		else
		{
			eqLogMessage(LogTrace, "Couldn't find model for %s.", params.name.c_str());
		}
	}
}