jPCT-AE - a 3d engine for Android > Support

Terrain and GenericVertexController..

(1/5) > >>

LowPolyMan:
I'm playing a bit with the terrain example (found on wiki) using a (heightmap) image. I added a cube and simple collisiondetection. It all works ok. Now i wanted to change the height of the terrain in realtime and i added a GenericVertexController, wich also works well. Now i like to change the height of the terrain only arround the location of the cube. The height of the terrain is stored in a float array terrain[][] and the height of the terrain in the GenericVertexController apply method is stored in a Mesh (SimpleVector[].y).

This is what i do now in my apply method:

--- Code: ---SimpleVector[] d = getDestinationMesh();
int tx = (int) (Cube.getTranslation().x + 640) / 10;  //The + 640, terrain starts at -640 ends at 640
int tz = (int) (Cube.getTranslation().z + 640) / 10;  //In reality it was -560 to 560.. very strange also
int i = 0;
terrain[tx][tz]=-256;
for (int x = 0; x < X_SIZE ; x++) {
for (int z = 0; z < Z_SIZE ; z++) {
d[i].y = terrain[x][z];
i++;
}
}
this.updateMesh();

--- End code ---

The above code does change the height on a certain location on the terrain, but not on the location of the cube. And i tried all kind of things. I must be doing something wrong..

EgonOlsen:
Have you checked the value for tx and tz and how they differ from the expected values?

LowPolyMan:

--- Quote from: EgonOlsen on March 21, 2013, 09:02:28 pm ---Have you checked the value for tx and tz and how they differ from the expected values?

--- End quote ---

Tnx for the fast reply but i seem to have fixed it, the apply code was correct but when creating the heightmap object i rotated it and add a new matrix. After uncommenting these lines it started to work right.

LowPolyMan:
Another question, about changing the texture at some point on the map, i found this example JPCT applet:

Applet http://www.paulscode.com/source/calcMinDistanceTest/
Code   http://www.paulscode.com/source/calcMinDistanceTest/MapClick.java

I tried this in JPCT AE but the texture never seems to change, mabe i made some error.

Code (from helloworld example):

--- Code: ---package com.threed.jpct.example;

import java.lang.reflect.Field;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.opengles.GL10;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.ViewGroup.LayoutParams;
import com.threed.jpct.Camera;
import com.threed.jpct.Config;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.Interact2D;
import com.threed.jpct.Light;
import com.threed.jpct.Logger;
import com.threed.jpct.Object3D;
import com.threed.jpct.OcTree;
import com.threed.jpct.RGBColor;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.Texture;
import com.threed.jpct.TextureManager;
import com.threed.jpct.World;
import com.threed.jpct.util.BitmapHelper;
import com.threed.jpct.util.MemoryHelper;

/**
 * A simple demo. This shows more how to use jPCT-AE than it shows how to write
 * a proper application for Android. It includes basic activity management to
 * handle pause and resume...
 *
 * @author EgonOlsen
 *
 */
@SuppressLint("NewApi")
public class HelloWorld extends Activity {

// Used to handle pause and resume...
private static HelloWorld master = null;
private GLSurfaceView mGLView;
private MyRenderer renderer = null;
private FrameBuffer fb = null;
private World world = null;
private Camera camera = null;
private RGBColor back = new RGBColor(50, 50, 100);
private float touchTurn = 0;
private float touchTurnUp = 0;
private float xpos = -1;
private float ypos = -1;
private Object3D terrain;
private int fps = 0;
private Light sun = null;
String status = "Loading..";
boolean status_midx=true;
boolean status_midy=true;
int polyIdOffset;
    private String outputLine1 = "";
    private String outputLine2 = "";
    private String outputLine3 = "";

protected void onCreate(Bundle savedInstanceState) {
Logger.log("onCreate");
if (master != null) {
copy(master);
}
super.onCreate(savedInstanceState);
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
mGLView = new GLSurfaceView(getApplication());
mGLView.setEGLConfigChooser(new GLSurfaceView.EGLConfigChooser() {
@SuppressLint("NewApi")
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
// Ensure that we get a 16bit framebuffer. Otherwise, we'll fall
// back to Pixelflinger on some device (read: Samsung I7500)
int[] attributes = new int[] { EGL10.EGL_DEPTH_SIZE, 16, EGL10.EGL_NONE };
EGLConfig[] configs = new EGLConfig[1];
int[] result = new int[1];
egl.eglChooseConfig(display, attributes, configs, 1, result);
return configs[0];
}
});
requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
renderer = new MyRenderer();
mGLView.setRenderer(renderer);
setContentView(mGLView);
        DrawOnTop mDraw = new DrawOnTop(this);
        addContentView(mDraw, new LayoutParams (LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
}

@Override
protected void onPause() {
super.onPause();
mGLView.onPause();
}

@Override
protected void onResume() {
super.onResume();
mGLView.onResume();
}

@Override
protected void onStop() {
super.onStop();
}

private void copy(Object src) {
try {
Logger.log("Copying data from master Activity!");
Field[] fs = src.getClass().getDeclaredFields();
for (Field f : fs) {
f.setAccessible(true);
f.set(this, f.get(src));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public boolean onTouchEvent(MotionEvent me) {
float x,y;
if (me.getAction() == MotionEvent.ACTION_DOWN) {
x = me.getX();
y = me.getY();
// Get the 3D coordinates in Camera space:
SimpleVector position = new SimpleVector(Interact2D.reproject2D3D(camera, fb, (int)x, (int)y));
// Convert the coordinates to World space:
position.matMul(camera.getBack().invert3x3());
position.add(camera.getPosition());
// Determine the direction from the camera position to the click
// point:
SimpleVector direction = position.calcSub(camera.getPosition()).normalize();
// Calculate the distance to whatever was clicked on:
float distance = world.calcMinDistance(position, direction, 10000);
// Check if we clicked on something:
if (distance == Object3D.COLLISION_NONE) {
// Nope, didn't click on anything. Reset the output messages:
outputLine1 = "No Collision";
outputLine2 = "";
outputLine3 = "";
} else {
// Calculate the exact 3D coordinates for the point that was
// clicked:
SimpleVector collisionPoint = new SimpleVector(direction);
collisionPoint.scalarMul(distance);
collisionPoint.add(position);
// Determine what cell of the map was clicked on (cells are
// 5x5):
int mapGridX = (int) collisionPoint.x / 5;
int mapGridY = (int) collisionPoint.z / 5;
// determine the polygon ID of the first triangle in the cell:
int polyId1 = ((32 * mapGridY + mapGridX) * 2) + polyIdOffset;
// Color both polygons in the cell Red:
terrain.getPolygonManager().setPolygonTexture(polyId1,
TextureManager.getInstance().getTextureID("Red"));
terrain.getPolygonManager().setPolygonTexture(polyId1 + 1,
TextureManager.getInstance().getTextureID("Red"));
// Generate the output messages:
outputLine1 = "Collision: " + collisionPoint;
outputLine2 = "    2D Map Coordinates: ( " + collisionPoint.x
+ ", " + collisionPoint.z + " )";
outputLine3 = "    Map Cell: ( " + mapGridX + ", " + mapGridY
+ " )";
}
return true;
}

if (me.getAction() == MotionEvent.ACTION_UP) {
xpos = -1;
ypos = -1;
touchTurn = 0;
touchTurnUp = 0;
return true;
}

if (me.getAction() == MotionEvent.ACTION_MOVE) {
float xd = me.getX() - xpos;
float yd = me.getY() - ypos;
xpos = me.getX();
ypos = me.getY();
touchTurn = xd / -100f;
touchTurnUp = yd / -100f;
return true;
}

try {
Thread.sleep(15);
} catch (Exception e) {
// No need for this...
}

return super.onTouchEvent(me);
}

protected boolean isFullscreenOpaque() {
return true;
}

class MyRenderer implements GLSurfaceView.Renderer {

private long time = System.currentTimeMillis();

public MyRenderer() {
Config.glTransparencyMul = (1.0f / 255);
        Config.glTransparencyOffset = (1.0f / 255);
        Config.farPlane = 10000;
        Config.maxPolysVisible = 10000;
}

public void onSurfaceChanged(GL10 gl, int w, int h) {
if (fb != null) {
fb.dispose();
}
fb = new FrameBuffer(gl, w, h);
if (master == null) {
world = new World();
world.setAmbientLight(50, 50, 50);
sun = new Light(world);
sun.setIntensity(20, 20, 20);
SimpleVector sv = new SimpleVector(80, -160, 80);
sun.setPosition(sv);

status = "Loading textures..";

// create some colorful textures to use on the terrain:
Texture Grey = new Texture(BitmapHelper.rescale(BitmapHelper.convert(getResources().getDrawable(R.drawable.grey)), 256, 256));
TextureManager.getInstance().addTexture("Grey", Grey);
Texture Red = new Texture(BitmapHelper.rescale(BitmapHelper.convert(getResources().getDrawable(R.drawable.red)), 256, 256));
TextureManager.getInstance().addTexture("Red", Red);

status = "Creating object..";
   
// create the terrain object and add it to the world:
        createTerrain();
        world.addObject( terrain );
        // set up the terrain object to receive collisions:
        terrain.setCollisionMode( Object3D.COLLISION_CHECK_OTHERS );
        // make sure all Object3Ds in the world are built:
        world.buildAllObjects();
       
        status = "Add camera and compact memory..";
       
        // set the camera position and orientation:
        camera = world.getCamera();
        camera.setPosition( -80, -160, -80 );
        camera.lookAt( new SimpleVector( 80, 0, 80 ) );

MemoryHelper.compact();

status = "";

if (master == null) {
Logger.log("Saving master Activity!");
master = HelloWorld.this;
}
}
}

// Generate the terrain Object3D:
    public void createTerrain()
    {
        int x, y;
        terrain = new Object3D( 2048 );  // specify the number of polys
        // Create the terrain's vertices (each cell size is 5x5):
        SimpleVector[][] vertices = new SimpleVector[33][33];
        for( y = 0; y < 33; y++ )
        {
            for( x = 0; x < 33; x++ )
            {
                vertices[x][y] = new SimpleVector( x * 5, 0, y * 5 );
            }
        }
        // Create the terrain's polys, set their UV coordinates,
        // and set their initial texture to grey:
        for( y = 0; y < 32; y++ )
        {
            for( x = 0; x < 32; x++ )
            {
                terrain.addTriangle( vertices[x][y+1], 0, 0,
                          vertices[x][y], 0, 1,
                          vertices[x+1][y], 1, 1,
                          TextureManager.getInstance().getTextureID( "Grey" ) );
                terrain.addTriangle( vertices[x+1][y], 1, 1,
                          vertices[x+1][y+1], 1, 0,
                          vertices[x][y+1], 0, 0,
                          TextureManager.getInstance().getTextureID( "Grey" ) );
            }
        }
        // build the Object3D (generates bounding box and normals):
        terrain.build();
        // Create an OcTrea for the terrain's mesh
        // (allows vertices to be changed later and optimizes speed)
        OcTree ocTree = new OcTree( terrain.getMesh(), 2048,
                                    OcTree.MODE_OPTIMIZED );
        // Optimizes collision detection on the OcTree:
        ocTree.setCollisionUse( OcTree.COLLISION_USE );
        // Assign the OcTree to the terrain Object3D:
        terrain.setOcTree( ocTree );
        // Determine the poly ID of the first polygon in the terrain object:
        polyIdOffset = terrain.getPolygonManager().getMaxPolygonID()
                       - terrain.getMesh().getTriangleCount();
    }

public void onSurfaceCreated(GL10 gl, EGLConfig config) {
status_midx=true;
status_midy=true;
status = "";
}

public void onDrawFrame(GL10 gl) {
if (touchTurn != 0) {
//cube.rotateY(touchTurn);
touchTurn = 0;
}
if (touchTurnUp != 0) {
//cube.rotateX(touchTurnUp);
touchTurnUp = 0;
}
status = outputLine1 + ", " + outputLine2 + ", " + outputLine3;
fb.clear(back);
world.renderScene(fb);
world.draw(fb);
fb.display();
if (System.currentTimeMillis() - time >= 1000) {
Logger.log(fps + "fps");
fps = 0;
time = System.currentTimeMillis();
}
fps++;
}
}
class DrawOnTop extends View {
Paint paint = new Paint();
Rect bounds = new Rect();
int x;
int y;
int tmpx;
int tmpy;
public DrawOnTop(Context context) {
super(context);
}
public void drawing(Canvas canvas) {
if (status.length() > 0) {
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.BLACK);
paint.setTextSize(48);
paint.setAntiAlias(true);
paint.setAlpha(255);
if (status_midx)
{
tmpx = (int) paint.measureText(status);
x = canvas.getWidth()/2 - (tmpx/2);
}
else
{
x = (canvas.getWidth() / 40);
}
if (status_midy)
{
paint.getTextBounds(status, 0, status.length(), bounds);
tmpy = bounds.bottom;
y = canvas.getHeight()/2 - (tmpy/2);
}
else
{
y = 48;
}
canvas.drawText(status, x - 1, y - 1, paint);
canvas.drawText(status, x + 1, y - 1, paint);
canvas.drawText(status, x + 1, y + 1, paint);
canvas.drawText(status, x - 1, y + 1, paint);
paint.setColor(Color.WHITE);
canvas.drawText(status, x, y, paint);
}
}
@Override
protected void onDraw(Canvas canvas) {
drawing(canvas);
super.onDraw(canvas);
this.invalidate();
}
}   

}

--- End code ---

LowPolyMan:
Just seen a post from 2010 where i read JPCT AE can't change texture after object is compiled, only the UV's can be changed... I quess this is still the case. :(

Navigation

[0] Message Index

[#] Next page

Go to full version