SVG rendering; Ballistic path calculation

Hey Everyone.

I managed to write a game design doc (https://docs.google.com/document/d/1JD18vqHkI5isv6qT_-IGet28PLvS31bgRwZCPWe38ck/edit?usp=sharing) with exact milestone plans hoping it will finally help me develop my game rather than just gamejamming and prototyping. I went through all of the problems I might have to implement and I see two area where I need little help.

  • UPDATE: Finally I found I can use nanovg. Zoomable SVG rendering. I’d like to import an SVG file (a world map) into my scene and render it in a way that is will be zoomable without quality issues. I found only one topic here: http://www.java-gaming.org/index.php?topic=14778.0 Do you have other sources I can check or an already existing tool I can use?
  • Mouse Pos to world pos: I’d like to later identify points on the map via lon-lat, as I think that’s the best way, but I have no idea how to do it as the map will be zoomable. So let’s say I’m over New York (zoomed in) and I’d like to get where exactly I am (lon-lat) based on the mouse cursor.
  • I’d like to calculate ballistic path from point A to point B (maybe using lon-lat coords). Am I right that this is what I’m talking about? https://en.wikipedia.org/wiki/Projectile_motion

Thank you!

1 Like

Sounds cool, if executed well this is the type of game that I’d want to play.

Thanks. It motivates me really, I just have not enough time to advance fast. I found out that rasterizing svgs with nanovg and rendering that way will not that be good in the end for various reasons. I found a good article in webgl how to triangulate svg paths hence I can build a VBO out of it.

There are some libs I might port to Java, if I won’t find anything better.

Here is the article: https://css-tricks.com/rendering-svg-paths-in-webgl/

I don’t want to open a new topic, so I ask a new one here. The best way I could solve the world map is using an obj file (https://blendermarket.com/products/3d-and-2d-world-map), so it can be zoomed without distortion and it’s easy to handle.

As a next step I wanted to put cities on the map via lat/lon. I use formulas found here: https://en.wikipedia.org/wiki/Equirectangular_projection

I tried it with these cities: Budapest, Rome, Cape Town. I’m definitely screwed up something as Budapest & Rome looks OK, but Cape Town is not. Any idea what I did wrong? The radius, standardParallels and centralMeridian are just guesses as I don’t really understood all, just the standardParallels.


    static Vector3f toWorldPos(float lat, float lon) {
        COORDS_TEMP.set(
                -x(lon),
                y(lat),
                0
        );
        System.out.println(String.format("X: %f Y: %f", COORDS_TEMP.x, COORDS_TEMP.y));
        return COORDS_TEMP;
    }

    private static float radius =0.4f;
    private static float standardParallels = 10.2f;
    private static float centralMeridian = 0f;

    static float x(float longitude) {
        return radius*(longitude-centralMeridian)*(float)Math.cos(standardParallels);
    }

    static float y(float latitude) {
        return radius*(latitude-standardParallels);
    }

The code I use for converting world space to screen space:


    private static final Vector4f WORLD_POS_TEMP = new Vector4f();
    private static final Vector4f CLIP_SPACE_TEMP = new Vector4f();
    private static final Vector3f NDC_SPACE_TEMP = new Vector3f();
    private static final Vector2f WINDOW_SPACE_TEMP = new Vector2f();
    private static final Vector2f WINDOW_SIZE_TEMP = new Vector2f();

    public static Vector2f convert(Vector3f worldPosition, Matrix4f projectionMatrix, Matrix4f viewMatrix) {
        WORLD_POS_TEMP.set(worldPosition, 1f);
        WINDOW_SIZE_TEMP.set(Engine.window.getPreferences().getWidth(), Engine.window.getPreferences().getHeight());

        CLIP_SPACE_TEMP.set(WORLD_POS_TEMP).mul(viewMatrix).mul(projectionMatrix);
        NDC_SPACE_TEMP.set(CLIP_SPACE_TEMP.x, -CLIP_SPACE_TEMP.y, CLIP_SPACE_TEMP.z).div(CLIP_SPACE_TEMP.w);
        WINDOW_SPACE_TEMP.set(NDC_SPACE_TEMP.x + 1f, NDC_SPACE_TEMP.y + 1f);
        WINDOW_SPACE_TEMP.set(WINDOW_SPACE_TEMP.x / 2f, WINDOW_SPACE_TEMP.y / 2f);
        WINDOW_SPACE_TEMP.mul(WINDOW_SIZE_TEMP);
        return WINDOW_SPACE_TEMP;
    }