Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I am using a standard heightmapped procedural terrain in my project. However, I want the terrain to appear spherical when the user zooms out. This is an attempt to simulate the appearance of a spherical planet. Here is my current algorithm:

        //get the direction from the "planet" center to this vert
        Vector3 sphereCentertoVertPosition = vert.Position - SphereCenter;
        sphereCentertoVertPosition.Normalize();

        //our rotation axis is the cross between the direction from this vert to the planet center and the root (center of the terrain) to the planet center
        RotationAxis = Vector3.Cross(sphereCentertoVertPosition, sphereCenterToRootPosition);

        //the amount we rotate is based on the distance of this vert from the center of the terrain
        Vector3 fromCenter = vert.Position - Root.Position;
        float amount = (fromCenter.Length() / ((myTextureWidth / Scale) / 2)) * (float)Math.PI;

        Quaternion rot = Quaternion.CreateFromAxisAngle(RotationAxis, amount);

        Vector3.Transform(ref vert.Position, ref rot, out vert.Position);

My main concern is that the rotation axis is not correct. Theoretically, should it be the cross between the vert-to-planet-center and the terrain-center-to-planet-center?

share|improve this question
    
What kind of result is this producing? –  Byte56 Dec 18 '11 at 6:54
    
1  
In case anyone googles this, there were three problems. First, the rotation axis should be Vector3.Cross(vert.Position - Root.Position, Vector3.Up); And second, Vector3.Transform will rotate around the origin. To rotate around the heightmap center, you need to subtract Root.Position, transform, and add Root.Position back. Third, you should only rotate PI/4 radians at the farthest points. –  khayman218 Dec 19 '11 at 17:40
add comment

1 Answer

up vote 4 down vote accepted

Hmm, I'm not so sure about rotating the vertices. Perhaps this is not the answer you're looking for, but I can suggest an alternate method.

I've done something similar with maps in my game. I wrote a shader to wrap terrain into a sphere, but it can easily be done outside the graphics card too. It's as simple as mapping the Cartesian coordinates to spherical coordinates. The code would look something like:

public static Vector3f MapToSphere(Vector3f coords, WorldMap MAP) {
    float pi = 3.14159265f;
    float thetaDelta = ((2 * pi) / (MAP.XSize - 1));
    float phiDelta = ((pi) / (MAP.ZSize - .5f));
    float RadiusBase = ((MAP.XSize) / pi / 2f);
    float theta = (coords.z * thetaDelta);
    float phi = (coords.x * phiDelta);

    //Limit the map to half a sphere
    if(theta > pi) {theta = theta - (pi);}

    if(theta < 0.0)    {theta = theta + (pi);}

    if (phi > 2*pi) {phi = phi - (2*pi);}

    if (phi < 0.0) {phi = phi + (2*pi);}

    Vector3f coords2 = new Vector3f();
    coords2.x = (float) (((RadiusBase) * Math.sin(theta) * Math.cos(phi)) + MAP.XSize / 2f);
    coords2.y = (float) ((RadiusBase) * Math.sin(theta) * Math.sin(phi));
    coords2.z = (float) (((RadiusBase) * Math.cos(theta)) + MAP.ZSize / 2f);
    return coords2;
}

This maybe "too spherical" for you. If so, you can try padding the edges of your map so that the portion turned into a sphere only represents a portion of the surface of the sphere.

Below is an example of the spherical mapping results.

A "flat" map:

enter image description here

And a spherical world, created by wrapping the vertices into a sphere:

enter image description here

Note that there will be a large amount of distortion at the poles if you don't follow the suggestion above to limit the surface area of the sphere this map is stretched over.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.