How to locate texture on sphere in jME3?

I would like to place JPEG texture map on sphere. It works for me, but I want to rotate texture by 180 degrees. I.e I want image to start not from zero UV coordinates, but earlier.

  1. you could modify the image so green wich is at image start <- would say this is the simplest solution
  2. you could create a own sphere with different uv coords
  3. you could create a own shader, that offsets the uv coords
  1. Don’t get so hung up one where 0 is on the mesh and just rotate the sphere by the appropriate amount.

Empire Phoenix, how to implement #2?

I have tried to set own coords (coinciding with lattitude x longitude) and have failed:

[java]package tests.com.jme3;

import java.nio.FloatBuffer;

import com.jme3.app.SimpleApplication;
import com.jme3.font.BitmapText;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.VertexBuffer;
import com.jme3.scene.VertexBuffer.Type;
import com.jme3.scene.VertexBuffer.Usage;
import com.jme3.scene.shape.Sphere;
import com.jme3.util.BufferUtils;

public class Try_TextureTransform extends SimpleApplication {

public static void main(String[] args) {
    Try_TextureTransform app = new Try_TextureTransform();
    app.setShowSettings(false);
    app.start(); // start the game
}

final float speed = 0.01f;

BitmapText hudText;
Sphere sphere1Mesh, sphere2Mesh;
Material sphere1Mat, sphere2Mat;
Geometry sphere1Geo, sphere2Geo;
Quaternion orientation;
DirectionalLight sun;

@Override
public void simpleInitApp() {

    flyCam.setEnabled(false);
    setDisplayStatView(false); 
    setDisplayFps(false);


    hudText = new BitmapText(guiFont, false);          
    hudText.setSize(guiFont.getCharSet().getRenderedSize());      // font size
    hudText.setColor(ColorRGBA.Blue);                             // font color
    hudText.setText("");             // the text
    hudText.setLocalTranslation(300, hudText.getLineHeight()*2, 0); // position
    guiNode.attachChild(hudText);

    sphere1Mesh = new Sphere(50, 50, 2);
    sphere1Mesh.setTextureMode(Sphere.TextureMode.Projected); // matrc

    sphere1Mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
    sphere1Mat.setTexture("ColorMap", assetManager.loadTexture("textures/Equirectangular_projection_SW.jpg"));

    sphere1Geo = new Geometry("Sphere2", sphere1Mesh);
    sphere1Geo.setMaterial(sphere1Mat); 
    sphere1Geo.setLocalTranslation(0, 0, 2);

    sphere2Mesh = new Sphere(50, 50, 2);

    VertexBuffer vb = sphere2Mesh.getBuffer(Type.Position);
    FloatBuffer fb = (FloatBuffer) vb.getData();
    float[] vertexCoordinates = BufferUtils.getFloatArray(fb);

    VertexBuffer vb2 = sphere2Mesh.getBuffer(Type.TexCoord);
    FloatBuffer fb2 = (FloatBuffer) vb2.getData();
    float[] uvCoordinates = BufferUtils.getFloatArray(fb2);

    double rho;
    for (int i = 0; i &lt; vertexCoordinates.length/3; ++i) {

        uvCoordinates[i*2] = (float) Math.atan2(vertexCoordinates[i*3+1], vertexCoordinates[i*3]);
        rho = Math.sqrt(Math.pow( vertexCoordinates[i*3], 2) + Math.pow( vertexCoordinates[i*3+1], 2));
        uvCoordinates[i*2+1] = (float) Math.atan2(vertexCoordinates[i*3+2], rho);
    }
  //apply new texture coordinates
    VertexBuffer uvCoordsBuffer = new VertexBuffer(Type.TexCoord);
    uvCoordsBuffer.setupData(Usage.Static, 2, com.jme3.scene.VertexBuffer.Format.Float, BufferUtils.createFloatBuffer(uvCoordinates));
    sphere2Mesh.clearBuffer(Type.TexCoord);
    sphere2Mesh.setBuffer(uvCoordsBuffer);


    //sphere2Mesh.setTextureMode(Sphere.TextureMode.Projected); // better quality on spheres

    sphere2Mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
    sphere2Mat.setTexture("ColorMap", assetManager.loadTexture("textures/Equirectangular_projection_SW.jpg"));

    sphere2Geo = new Geometry("Sphere2", sphere2Mesh);
    sphere2Geo.setMaterial(sphere2Mat); 
    sphere2Geo.setLocalTranslation(0, 0, -2);

    cam.setLocation(new Vector3f(-10, 0, 0));
    cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Z);

    rootNode.attachChild(sphere1Geo);
    rootNode.attachChild(sphere2Geo); 

}

@Override
public void simpleUpdate(float tpf) {


    Vector2f cursorPosition = inputManager.getCursorPosition();
    Vector3f cursorPositionWorld = cam.getWorldCoordinates(cursorPosition, 1);

    orientation = new Quaternion().fromAngleAxis(cursorPositionWorld.z*speed, Vector3f.UNIT_Y);
    orientation.multLocal(new Quaternion().fromAngleAxis(-cursorPositionWorld.y*speed, Vector3f.UNIT_Z));

    rootNode.setLocalRotation(orientation);



}

}[/java]

it gave me