6
« on: September 29, 2009, 02:02:04 pm »
Hi.
I improved my Flight-Sim Project a bit. The Horizon is working well now. I'm using a big plane, rotating dynamically with the camera. That solution is IMHO better and simpler than the one with two domes...
You can look around with arrowkeys, and move around with w,a,s,d keys.
One problem is, when you move high above the ground, the landing-pad isn't drawn properly. I suppose it's a math-rounding issue of the painter-algorithm; I tried to lower the ground-plane a little bit, to avoid this problem, but if you fly far away from ground, this "little bit" gets too small...
I tried to play around with the setSortOffset() method on the ground-plane, but it didn't chance anything... do you have any suggestions??
Here is my code:
import com.threed.jpct.*;
import javax.swing.*;
import java.awt.Color;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class HorizonTest implements KeyListener {
private static float PI = (float) Math.PI;
private World world = null;
private FrameBuffer buffer = null;
private Object3D box = null;
private Object3D plane = null;
private Object3D[] grid = null;
private Object3D[] wobjects = null;
private JFrame frame = null;
// half size of the grid
int gridsize_x = 6;
int gridsize_z = 6;
// Rotation control variables
private boolean doLeftRotation = false;
private boolean doRightRotation = false;
private boolean doUpRotation = false;
private boolean doDownRotation = false;
private boolean doMoveForward = false;
private boolean doMoveBackward = false;
private boolean doRollLeft = false;
private boolean doRollRight = false;
float xpos=-200, ypos=-50, zpos=0;
float xangle=0, yangle=0, zangle=0;
int oldcx=0, oldcz=0;
public static void main(String[] args) throws Exception {
new HorizonTest().loop();
}
public HorizonTest() throws Exception {
// Setup the frame
frame = new JFrame("Horizon Test");
frame.setSize(800, 600);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
frame.addKeyListener(this);
Config.farPlane = 1700;
// Set up the worlds
world = new World();
//world.setAmbientLight(127, 127, 127);
world.setAmbientLight(255, 255, 255);
// Define textures
TextureManager.getInstance().addTexture("earth", new Texture(16,16,new Color(0,170,0)));
TextureManager.getInstance().addTexture("sky", new Texture(16,16,new Color(85,255,255)));
TextureManager.getInstance().addTexture("red", new Texture(16,16,new Color(255,0,0)));
TextureManager.getInstance().addTexture("grid", new Texture(16,16,new Color(85,85,85)));
TextureManager.getInstance().addTexture("landingpad", new Texture(16,16,new Color(200,200,200)));
// Some box somewhere else
box = Primitives.getBox(10f, 1f);
box.translate(0, -10f, -100f); // Place it on the ground
box.getPolygonManager().setPolygonTexture(8, 3);
box.rotateY(PI / 4f);
world.addObject(box);
// Add ground-grid
int count = 0;
grid = new Object3D[gridsize_x*gridsize_z*4];
for (int z=-gridsize_z; z<gridsize_z; z++) {
for (int x=-gridsize_x; x<gridsize_x; x++) {
grid[count] = Primitives.getBox(1f, 1f);
grid[count].setTexture("grid");
grid[count].translate(200 * x, -1f, 200 * z); // Place it on the ground
world.addObject(grid[count]);
count++;
}
}
// Horizon plane
plane = Primitives.getPlane(1, 10000);
plane.setTexture("earth");
plane.translate(0, 1f, 0);
plane.rotateX(PI / 2f);
world.addObject(plane);
addLandingPad();
world.buildAllObjects();
// View
Camera cam = world.getCamera();
cam.setFOV(1.5f);
}
private void loop() throws Exception {
buffer = new FrameBuffer(800, 600, FrameBuffer.SAMPLINGMODE_NORMAL);
while (frame.isShowing()) {
doMovementUpdate();
buffer.clear(new Color(85,255,255));
world.renderScene(buffer);
world.draw(buffer);
buffer.update();
buffer.display(frame.getGraphics(),0,0);
Thread.sleep(10);
}
buffer.disableRenderer(IRenderer.RENDERER_OPENGL);
buffer.dispose();
frame.dispose();
System.exit(0);
}
private void addLandingPad() {
int numobjects = 1;
wobjects = new Object3D[numobjects];
wobjects[0] = new Object3D(2);
wobjects[0].addTriangle(new SimpleVector(0,0,0),new SimpleVector(100,0,0),new SimpleVector(0,0,1000));
wobjects[0].addTriangle(new SimpleVector(100,0,1000),new SimpleVector(100,0,0),new SimpleVector(0,0,1000));
wobjects[0].rotateY(PI / 2f);
wobjects[0].translate(100,0,-450);
wobjects[0].setTexture("landingpad");
wobjects[0].setCulling(false);
world.addObject(wobjects[0]);
}
private void updateGrid() {
SimpleVector v = world.getCamera().getPosition();
int cx = Math.round(v.x / 200) * 200;
int cz = Math.round(v.z / 200) * 200;
int dx = cx - oldcx;
int dz = cz - oldcz;
for (int i=0; i<grid.length; i++) {
grid[i].translate(dx, 0, dz);
}
plane.translate(dx, 0, dz);
oldcx = cx;
oldcz = cz;
}
// Rotates the horizon plane with the camera
private void updateHorizon(float angle) {
plane.rotateY(angle);
}
private void doMovementUpdate() {
float rotval= 0.01f;
float speed = 1.3f; // default = 1.3f
if (doLeftRotation) {
yangle -= rotval;
updateHorizon(-rotval);
}
if (doRightRotation) {
yangle += rotval;
updateHorizon(rotval);
}
if (doUpRotation) {
xangle -= rotval;
}
if (doDownRotation) {
xangle += rotval;
}
if (doMoveForward) {
if (ypos > -4) {
world.getCamera().rotateX(xangle);
world.getCamera().rotateZ(zangle);
xangle=0;
zangle=0;
world.getCamera().moveCamera(Camera.CAMERA_MOVEUP, 1);
}
world.getCamera().moveCamera(Camera.CAMERA_MOVEIN, speed);
SimpleVector v = world.getCamera().getPosition();
xpos = v.x;
ypos = v.y;
zpos = v.z;
updateGrid();
}
if (doMoveBackward) {
if (ypos > -4) {
world.getCamera().rotateX(xangle);
world.getCamera().rotateZ(zangle);
xangle=0;
zangle=0;
world.getCamera().moveCamera(Camera.CAMERA_MOVEUP, 1);
}
world.getCamera().moveCamera(Camera.CAMERA_MOVEOUT, speed);
SimpleVector v = world.getCamera().getPosition();
xpos = v.x;
ypos = v.y;
zpos = v.z;
updateGrid();
}
if (doRollLeft) {
zangle += rotval;
}
if (doRollRight) {
zangle -= rotval;
}
world.getCamera().setPosition(xpos,ypos,zpos);
world.getCamera().lookAt(new SimpleVector(xpos+1,ypos,zpos));
world.getCamera().rotateY(-yangle);
world.getCamera().rotateX(-xangle);
world.getCamera().rotateZ(-zangle);
System.out.println("pos(" + Math.round(xpos/100) + "," + Math.round(zpos/100) + ")");
}
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
//System.out.println("key code : " + keyCode);
if (keyCode == 37) { // left arrow
doLeftRotation = true;
}
else if (keyCode == 39) { // right arrow
doRightRotation = true;
}
else if (keyCode == 38) { // up arrow
doUpRotation = true;
}
else if (keyCode == 40) { // down arrow
doDownRotation = true;
}
else if (keyCode == 87) { // "w"
doMoveForward = true;
}
else if (keyCode == 83) { // "s"
doMoveBackward = true;
}
else if (keyCode == 65) { // "a"
doRollLeft = true;
}
else if (keyCode == 68) { // "d"
doRollRight = true;
}
}
@Override
public void keyReleased(KeyEvent e) {
int keyCode = e.getKeyCode();
//System.out.println("key code : " + keyCode);
if (keyCode == 37) { // left arrow
doLeftRotation = false;
}
else if (keyCode == 39) { // right arrow
doRightRotation = false;
}
else if (keyCode == 38) { // up arrow
doUpRotation = false;
}
else if (keyCode == 40) { // down arrow
doDownRotation = false;
}
else if (keyCode == 87) { // "w"
doMoveForward = false;
}
else if (keyCode == 83) { // "s"
doMoveBackward = false;
}
else if (keyCode == 65) { // "a"
doRollLeft = false;
}
else if (keyCode == 68) { // "d"
doRollRight = false;
}
}
@Override
public void keyTyped(KeyEvent e) {
}
private void tileTexture(Object3D obj, float tileFactor) {
PolygonManager pm = obj.getPolygonManager();
int end = pm.getMaxPolygonID();
for (int i = 0; i < end; i++) {
SimpleVector uv0 = pm.getTextureUV(i, 0);
SimpleVector uv1 = pm.getTextureUV(i, 1);
SimpleVector uv2 = pm.getTextureUV(i, 2);
uv0.scalarMul(tileFactor);
uv1.scalarMul(tileFactor);
uv2.scalarMul(tileFactor);
int id = pm.getPolygonTexture(i);
TextureInfo ti = new TextureInfo(id, uv0.x, uv0.y, uv1.x, uv1.y,
uv2.x, uv2.y);
pm.setPolygonTexture(i, ti);
}
}
}