JPEG テクスチャ マップを球体に配置したいと考えています。私にはうまくいきますが、テクスチャを180度回転させたいです。つまり、画像をゼロの UV 座標からではなく、より早く開始したいのです。
アップデート
球のテクスチャ座標を再割り当てしようとしました。テクスチャ座標は float であり、[0..1] の範囲に制限されないことを望んでいました。それ以外の場合は、画像を [0..1 x 0..1] の領域に配置する必要があります。
それは後者のようなことをしましたが、正確ではありません:
つまり、画像全体が球の小さな領域に入れられました。しかし、それが配置されているこの正確な領域は、 の負の値に対応していますU
。つまり、同じ経度にあり、以前の実験で画像の余白があった場所 (上の球体) です。
なんで?
画像はこちら: https://en.wikipedia.org/wiki/File:Equirectangular_projection_SW.jpg
コードは次のとおりです。
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 < 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);
}
}