jPCT-AE - a 3d engine for Android > Support
Terrain and GenericVertexController..
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