Beispiel #1
0
void CMouseHandler::DrawSelectionBox()
{
	dir = hide ? camera->forward : camera->CalcPixelDir(lastx, lasty);
	if (activeReceiver) {
		return;
	}

	if (gu->fpsMode) {
		return;
	}

	ButtonPressEvt& bp = buttons[SDL_BUTTON_LEFT];

	if (bp.pressed && !bp.chorded && (bp.movement > 4) &&
	   (!inMapDrawer || !inMapDrawer->IsDrawMode()))
	{
		float2 topright, btmleft;
		GetSelectionBoxCoeff(bp.camPos, bp.dir, camera->pos, dir, topright, btmleft);

		float3 dir1S = camera->right * topright.x;
		float3 dir1U = camera->up    * topright.y;
		float3 dir2S = camera->right * btmleft.x;
		float3 dir2U = camera->up    * btmleft.y;

		glColor4fv(cmdColors.mouseBox);

		glPushAttrib(GL_ENABLE_BIT);

		glDisable(GL_FOG);
		glDisable(GL_DEPTH_TEST);
		glDisable(GL_TEXTURE_2D);

		glEnable(GL_BLEND);
		glBlendFunc((GLenum)cmdColors.MouseBoxBlendSrc(),
		            (GLenum)cmdColors.MouseBoxBlendDst());

		glLineWidth(cmdColors.MouseBoxLineWidth());

		float3 verts[] = {
			camera->pos + (dir1U + dir1S + camera->forward) * 30,
			camera->pos + (dir2U + dir1S + camera->forward) * 30,
			camera->pos + (dir2U + dir2S + camera->forward) * 30,
			camera->pos + (dir1U + dir2S + camera->forward) * 30,
		};

		glEnableClientState(GL_VERTEX_ARRAY);
		glVertexPointer(3, GL_FLOAT, 0, verts);
		glDrawArrays(GL_LINE_LOOP, 0, 4);
		glDisableClientState(GL_VERTEX_ARRAY);

		glLineWidth(1.0f);

		glPopAttrib();
	}
}
Beispiel #2
0
void CMouseHandler::MouseRelease(int x, int y, int button)
{
	if (button > NUM_BUTTONS)
		return;

	camHandler->GetCurrentController().MouseRelease(x, y, button);

	dir = hide ? camera->forward : camera->CalcPixelDir(x, y);
	buttons[button].pressed = false;

	if (inMapDrawer && inMapDrawer->IsDrawMode()){
		inMapDrawer->MouseRelease(x, y, button);
		return;
	}

	if (activeReceiver) {
		activeReceiver->MouseRelease(x, y, button);
		if(!buttons[SDL_BUTTON_LEFT].pressed && !buttons[SDL_BUTTON_MIDDLE].pressed && !buttons[SDL_BUTTON_RIGHT].pressed)
			activeReceiver = NULL;
		return;
	}

	GML_RECMUTEX_LOCK(sel); //FIXME redundant? (selectedUnits already has mutexes)

	// Switch camera mode on a middle click that wasn't a middle mouse drag scroll.
	// the latter is determined by the time the mouse was held down:
	// switch (dragScrollThreshold)
	//   <= means a camera mode switch
	//    > means a drag scroll
	if (button == SDL_BUTTON_MIDDLE) {
		if (buttons[SDL_BUTTON_MIDDLE].time > (gu->gameTime - dragScrollThreshold))
			ToggleMiddleClickScroll();
		return;
	}

	if (gu->fpsMode) {
		return;
	}

	if ((button == SDL_BUTTON_LEFT) && !buttons[button].chorded) {
		ButtonPressEvt& bp = buttons[SDL_BUTTON_LEFT];

		if (!keyInput->IsKeyPressed(SDLK_LSHIFT) && !keyInput->IsKeyPressed(SDLK_LCTRL)) {
			selectedUnits.ClearSelected();
		}

		if (bp.movement > 4) {
			// select box
			float2 topright, btmleft;
			GetSelectionBoxCoeff(bp.camPos, bp.dir, camera->pos, dir, topright, btmleft);

			// GetSelectionBoxCoeff returns us the corner pos, but we want to do a inview frustum check.
			// To do so we need the frustum planes (= plane normal + plane offset).
			float3 norm1 = camera->up;
			float3 norm2 = -camera->up;
			float3 norm3 = camera->right;
			float3 norm4 = -camera->right;

			#define signf(x) ((x>0.0f) ? 1.0f : -1)
			if (topright.y != 0) norm1 = (camera->forward * signf(-topright.y)) + (camera->up / math::fabs(topright.y));
			if (btmleft.y  != 0) norm2 = (camera->forward * signf(  btmleft.y)) - (camera->up / math::fabs(btmleft.y));
			if (topright.x != 0) norm3 = (camera->forward * signf(-topright.x)) + (camera->right / math::fabs(topright.x));
			if (btmleft.x  != 0) norm4 = (camera->forward * signf(  btmleft.x)) - (camera->right / math::fabs(btmleft.x));

			const float4 plane1(norm1, -(norm1.dot(camera->pos)));
			const float4 plane2(norm2, -(norm2.dot(camera->pos)));
			const float4 plane3(norm3, -(norm3.dot(camera->pos)));
			const float4 plane4(norm4, -(norm4.dot(camera->pos)));

			selectedUnits.HandleUnitBoxSelection(plane1, plane2, plane3, plane4);
		} else {
			CUnit* unit;
			CFeature* feature;
			TraceRay::GuiTraceRay(camera->pos, dir, globalRendering->viewRange * 1.4f, NULL, unit, feature, false);

			selectedUnits.HandleSingleUnitClickSelection(unit, true);
		}

		bp.lastRelease = gu->gameTime;
	}
}
Beispiel #3
0
void CMouseHandler::MouseRelease(int x, int y, int button)
{
	const CUnit *_lastClicked = lastClicked;
	lastClicked = nullptr;

	if (button > NUM_BUTTONS)
		return;

	dir = hide ? camera->GetDir() : camera->CalcPixelDir(x, y);

	buttons[button].pressed = false;

	if (inMapDrawer && inMapDrawer->IsDrawMode()){
		inMapDrawer->MouseRelease(x, y, button);
		return;
	}

	if (activeReceiver != nullptr) {
		activeReceiver->MouseRelease(x, y, button);

		if (!buttons[SDL_BUTTON_LEFT].pressed && !buttons[SDL_BUTTON_MIDDLE].pressed && !buttons[SDL_BUTTON_RIGHT].pressed)
			activeReceiver = nullptr;

		return;
	}

	// Switch camera mode on a middle click that wasn't a middle mouse drag scroll.
	// the latter is determined by the time the mouse was held down:
	// switch (dragScrollThreshold)
	//   <= means a camera mode switch
	//    > means a drag scroll
	if (button == SDL_BUTTON_MIDDLE) {
		if (buttons[SDL_BUTTON_MIDDLE].time > (gu->gameTime - dragScrollThreshold))
			ToggleMiddleClickScroll();
		return;
	}

	if (gu->fpsMode)
		return;
	// outside game, neither guiHandler nor quadField exist and TraceRay would crash
	if (guihandler == nullptr)
		return;

	if ((button == SDL_BUTTON_LEFT) && !buttons[button].chorded) {
		ButtonPressEvt& bp = buttons[SDL_BUTTON_LEFT];

		if (!KeyInput::GetKeyModState(KMOD_SHIFT) && !KeyInput::GetKeyModState(KMOD_CTRL))
			selectedUnitsHandler.ClearSelected();

		if (bp.movement > 4) {
			// select box
			float2 topright, btmleft;
			GetSelectionBoxCoeff(bp.camPos, bp.dir, camera->GetPos(), dir, topright, btmleft);

			// GetSelectionBoxCoeff returns us the corner pos, but we want to do a inview frustum check.
			// To do so we need the frustum planes (= plane normal + plane offset).
			float3 norm1 = camera->GetUp();
			float3 norm2 = -camera->GetUp();
			float3 norm3 = camera->GetRight();
			float3 norm4 = -camera->GetRight();

			#define signf(x) ((x>0.0f) ? 1.0f : -1)
			if (topright.y != 0) norm1 = (camera->GetDir() * signf(-topright.y)) + (camera->GetUp() / math::fabs(topright.y));
			if (btmleft.y  != 0) norm2 = (camera->GetDir() * signf(  btmleft.y)) - (camera->GetUp() / math::fabs(btmleft.y));
			if (topright.x != 0) norm3 = (camera->GetDir() * signf(-topright.x)) + (camera->GetRight() / math::fabs(topright.x));
			if (btmleft.x  != 0) norm4 = (camera->GetDir() * signf(  btmleft.x)) - (camera->GetRight() / math::fabs(btmleft.x));

			const float4 plane1(norm1, -(norm1.dot(camera->GetPos())));
			const float4 plane2(norm2, -(norm2.dot(camera->GetPos())));
			const float4 plane3(norm3, -(norm3.dot(camera->GetPos())));
			const float4 plane4(norm4, -(norm4.dot(camera->GetPos())));

			selectedUnitsHandler.HandleUnitBoxSelection(plane1, plane2, plane3, plane4);
		} else {
			const CUnit* unit = nullptr;
			const CFeature* feature = nullptr;

			TraceRay::GuiTraceRay(camera->GetPos(), dir, globalRendering->viewRange * 1.4f, NULL, unit, feature, false);
			lastClicked = unit;

			const bool selectType = (bp.lastRelease >= (gu->gameTime - doubleClickTime) && unit == _lastClicked);

			selectedUnitsHandler.HandleSingleUnitClickSelection(const_cast<CUnit*>(unit), true, selectType);
		}

		bp.lastRelease = gu->gameTime;
	}
}