I would consider generating waypoint graphs instead. They're easy to work with, they give optimal paths, and are generally fast enough for reasonably small environments.
The optimal path will be a series of line segments, and each vertex in the path will either be the origin, the destination, or a vertex of one of your obstacles. So although your environment isn't discreet, you only really need to consider this discreet set of vertices.
So, you can build a waypoint graph with a node for the origin, a node for the destination, and a node for each vertex of each obstacle. Two nodes should have an edge between them iff the line segment between the nodes does not intersect any obstacles. The weight of the edge should be the length of this line segment.
If you have dynamic obstacles, a new graph will need to be regenerated repeatedly. If this turns out to be too slow, a number of optimizations are possible, but the best approach depends on how many static vs dynamic obstacles you have and how often the dynamic ones move.
Once you have this graph, you can run any pathfinding algorithm on it. A* is an option - it's usually used with grids, but all it requires is a graph and a distance heuristic. Since each node in your graph has spacial coordinates associated with it, you can use the usual distance heuristics (e.g., Euclidean distance if you allow movement in any direction).
Note that I've assumed your agents can fit though arbitrarily small spaces. If that isn't the case, we need to offset waypoints away from obstacles based on the agents' size, and use rectangles instead of line segments when checking if two nodes are connected.