【发布时间】:2014-07-06 12:27:43
【问题描述】:
我想在球体上放置 JPEG 纹理贴图。它对我有用,但我想将纹理旋转 180 度。即我希望图像不是从零 UV 坐标开始,而是更早。
更新
我尝试重新分配球体的纹理坐标。纹理坐标是浮动的,我希望它们不会被限制在 [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);
}
}
【问题讨论】:
-
可能会更容易旋转球体本身或使纹理与您的 UV 坐标一致。 UV 坐标定义了纹理“固定”到形状的位置,所以如果你能做到这一点,那将是一个令人讨厌的 hack
-
坐标是固定的,为什么图片也要固定呢?
-
O,所以你的意思是你想在 Java 中从旧图像创建一个新图像?如果你只做一次,当然可以,但在 Java 之外更容易做。在任何图像处理程序中,您都可以在 30 秒内完成
-
我无法在图形编辑器中做到精确(我们正在谈论地图)。另外,我知道 Java 有可能,但想知道 JME 中是否有可能。
-
JME 是 Java 之上的一个库(我知道你知道,我在强调),复制核心功能会浪费他们的时间
标签: java 3d jmonkeyengine uv-mapping