void MouseUpDraw() { if (shape == Line || shape == Poly) { DrawLineXor(p0_x, p0_y, p1_x, p1_y); DrawLine(p0_x, p0_y, p1_x, p1_y); p0_x = p1_x = mouse_x; p0_y = p1_y = mouse_y; if (shape == Poly) { if (polygon.n > 0 && (polygon.vertex[polygon.n - 1].x != p0_x || polygon.vertex[polygon.n - 1].y != p0_y)) InsertVertex(polygon, p0_x, p0_y); } else if (shape == Line) { float xf1, yf1, xf2, yf2; GetWorldCoordinates(x_1, y_1, &xf1, &yf1); GetWorldCoordinates(x_2, y_2, &xf2, &yf2); entities.push_back(new LineEntity(xf1, yf1, xf2, yf2)); } } if (shape == Circle) { DrawCircle(p0_x, p0_y, r); float x0, y0, rx, ry; GetWorldCoordinates(x_1, y_1, &x0, &y0); GetWorldCoordinates(x_1 + r, y_1 + r, &rx, &ry); rx = abs(rx - x0); ry = abs(ry - y0); entities.push_back(new EllipseEntity(x0, y0, rx, ry)); } mouse_action = NO_ACTION; }
void MouseUpZoom() { DrawZoomRectangle(); float xf0, yf0, xf1, yf1; GetWorldCoordinates(p0_x, p0_y, &xf0, &yf0); GetWorldCoordinates(p1_x, p1_y, &xf1, &yf1); float aux_x = xf0 + xf1; float aux_y = yf0 + yf1; xf0 = min(xf0, xf1); yf0 = min(yf0, yf1); xf1 = aux_x - xf0; yf1 = aux_y - yf0; SetWindow(xf0, xf1, yf0, yf1); ReDrawAll(); mouse_action = NO_ACTION; }
Bool PickObjectTool::GetCursorInfo(BaseDocument* doc, BaseContainer& data, BaseDraw* bd, Float x, Float y, BaseContainer& bc) { if (bc.GetId() == BFM_CURSORINFO_REMOVE) { _lastBaseDraw = nullptr; } else { _lastBaseDraw = bd; _mouseX = (Int32)x; _mouseY = (Int32)y; AutoAlloc<C4DObjectList> list; if (list) { // get the z position of the topmost object. The z range for objects is from -1 to 1. Float z = 1.0; String str; Matrix4d m; ViewportSelect::PickObject(bd, doc, _mouseX, _mouseY, 1, VIEWPORT_PICK_FLAGS_ALLOW_OGL | VIEWPORT_PICK_FLAGS_USE_SEL_FILTER | VIEWPORT_PICK_FLAGS_OGL_ONLY_TOPMOST, nullptr, list, &m); if (list->GetCount() > 0) z = list->GetZ(0); if (z < 1.0) { Vector v = GetWorldCoordinates(bd, m, x, y, z); char ch[200]; sprintf(ch, "Mouse coordinates: (%d, %d), world coordinates: (%.4f, %.4f, %.4f)", _mouseX, _mouseY, v.x, v.y, v.z); str = ch; } else { str = "Mouse cursor is not over an object"; } StatusSetText(str); } } SpecialEventAdd(EVMSG_UPDATEHIGHLIGHT); return true; }
CVector3D CCamera::GetWorldCoordinates(int px, int py, bool aboveWater) const { CHFTracer tracer(g_Game->GetWorld()->GetTerrain()); int x, z; CVector3D origin, dir, delta, terrainPoint, waterPoint; BuildCameraRay(px, py, origin, dir); bool gotTerrain = tracer.RayIntersect(origin, dir, x, z, terrainPoint); if (!aboveWater) { if (gotTerrain) return terrainPoint; // Off the edge of the world? // Work out where it /would/ hit, if the map were extended out to infinity with average height. return GetWorldCoordinates(px, py, 50.0f); } CPlane plane; plane.Set(CVector3D(0.f, 1.f, 0.f), // upwards normal CVector3D(0.f, g_Renderer.GetWaterManager()->m_WaterHeight, 0.f)); // passes through water plane bool gotWater = plane.FindRayIntersection( origin, dir, &waterPoint ); // Clamp the water intersection to within the map's bounds, so that // we'll always return a valid position on the map ssize_t mapSize = g_Game->GetWorld()->GetTerrain()->GetVerticesPerSide(); if (gotWater) { waterPoint.X = clamp(waterPoint.X, 0.f, (float)((mapSize-1)*TERRAIN_TILE_SIZE)); waterPoint.Z = clamp(waterPoint.Z, 0.f, (float)((mapSize-1)*TERRAIN_TILE_SIZE)); } if (gotTerrain) { if (gotWater) { // Intersecting both heightmap and water plane; choose the closest of those if ((origin - terrainPoint).LengthSquared() < (origin - waterPoint).LengthSquared()) return terrainPoint; else return waterPoint; } else { // Intersecting heightmap but parallel to water plane return terrainPoint; } } else { if (gotWater) { // Only intersecting water plane return waterPoint; } else { // Not intersecting terrain or water; just return 0,0,0. return CVector3D(0.f, 0.f, 0.f); } } }