Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - iamfoolberg

Pages: [1]
1
Support / Integrating jPCT in NASA 3D GIS WorldWind
« on: September 12, 2015, 11:29:56 am »
In order to draw 3d animations in WorldWind, i'm trying to introducing jPCT into it.
The idea is simple: 1.inject WW's GL2 object into jPCT, 2. jPCT draws all of its Object3ds on the GL2, 3. A WW's layer is used to wrap 1 & 2.

Firstly, i write a ww's layer Jpct3DLayer which extends ww's AbstractLayer.

In the method doRender(), which will be called back when the WW is request to update, the following operations are performed:
1. store all WW's GL matrix.
2. inject the WW's GL into jPCT if it is not the same as last injected.
3. set the camera location to WW's eyepoint, the coordinates are adjusted from (x,y,z) to (x,-y,-z).
4. call jPCT to repaint its world.
5. force jPCT  to draw its scene into injected GL.
6. restore all WW's GL matrix.

To test the jPCT layer, i load a .3ds file with a .jpg texture. And rotate the 3d object continously.

The layer looks like:
Code: [Select]
package org.aoe.det.ww.d3man.ww;

import java.awt.Canvas;
import javax.media.opengl.GL;
import javax.media.opengl.GL2;

import org.aoe.det.ww.d3man.D3Man;
import org.gbzh.util.log.Log;
import org.gbzh.util.resource.Resource;

import com.threed.jpct.FrameBuffer;
import com.threed.jpct.IRenderer;
import com.threed.jpct.Loader;
import com.threed.jpct.Object3D;
import com.threed.jpct.Primitives;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.Texture;
import com.threed.jpct.TextureManager;
import com.threed.jpct.Util;
import com.threed.jpct.World;

import gov.nasa.worldwind.geom.Position;
import gov.nasa.worldwind.geom.Vec4;
import gov.nasa.worldwind.layers.AbstractLayer;
import gov.nasa.worldwind.render.DrawContext;

/**
 * A jPCT based three model layer. In jPCT, positive x goes to the right,
 * positive z goes INTO the screen and positive y goes DOWN. In worldwind,
 * positive x goes to the right, positive z goes OUT the screen and positive
 * goes UP. In worldwind,cartesian coordinates's point(0, 0, radius of the
 * earth) has the longi/lati-tude position(0, 0, radius of the earth). longitude
 * goes RIGHT to +180 and left to -180, latitude goes UP to +90 and down to -90.
 *
 * @author berg
 *
 */
public class Jpct3DLayer extends AbstractLayer {
/** The world of jPCT. */
public World world;
/***/
public FrameBuffer buffer;
public GL2 lastGL;
public Canvas canvas;
public Object3D box;

public Jpct3DLayer() {
this.world = new World();
this.world.setAmbientLight(255, 255, 255);

TextureManager.getInstance().addTexture("box",
new Texture(Resource.getResource("data/red.jpg")));

Object3D[] objs=Loader.load3DS(Resource.getResource("data/spaceship3.3ds"), 1);
    if (objs.length>0) {
    box = Object3D.mergeAll(objs);
    box.scale(0.3f);
    }else{      
    box = Primitives.getBox(13f, 2f);
    }

box.setTexture("box");
box.setEnvmapped(Object3D.ENVMAP_ENABLED);
box.build();
world.addObject(box);
Position boxPos = Position.fromDegrees(0, 20, 16000);
Position camPos = Position.fromDegrees(0, 20, 16000);

setObject3DPosition(box, ww2jpct(boxPos));
this.world.getCamera().setPosition(ww2jpct(camPos));
this.world.getCamera().lookAt(ww2jpct(boxPos));



new Thread(){//rotate the box
@Override
public void run() {
while(true){
box.rotateZ(0.1f);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
/**
* prepare a jPCT FrameBuffer for given width&height.
* @param width
* @param height
*/
private void preparejPCTBuffer(int width, int height) {
method: do {
if(this.buffer!=null){
if(this.buffer.getHeight()!=height || this.buffer.getWidth()!=width){
this.buffer.dispose();
this.buffer = null;
}
}
if(this.buffer == null){
this.buffer = new FrameBuffer(width, height,
FrameBuffer.SAMPLINGMODE_NORMAL);

canvas = buffer.enableGLCanvasRenderer();
buffer.disableRenderer(IRenderer.RENDERER_SOFTWARE);
}
break method;
} while (false);
}

// puts opengl in the correct state for this layer
protected void beginDraw(DrawContext dc) {
GL2 gl = (GL2) dc.getGL();

// gl.glPushAttrib(GL2.GL_TEXTURE_BIT | GL2.GL_ENABLE_BIT
// | GL2.GL_CURRENT_BIT | GL2.GL_TRANSFORM_BIT);
gl.glPushAttrib(GL2.GL_ALL_ATTRIB_BITS);

// if (!dc.isPickingMode()) {
// gl.glEnable(GL.GL_BLEND);
// gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
// }

gl.glMatrixMode(GL2.GL_MODELVIEW);//|GL2.GL_PROJECTION|GL2.GL_TEXTURE);
gl.glPushMatrix();
gl.glLoadIdentity();
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glPushMatrix();
gl.glLoadIdentity();
gl.glMatrixMode(GL2.GL_TEXTURE);
gl.glPushMatrix();
gl.glLoadIdentity();

gl.glMatrixPushEXT(GL2.GL_MODELVIEW);
gl.glMatrixPushEXT(GL2.GL_PROJECTION);
gl.glMatrixPushEXT(GL2.GL_TEXTURE);
this.preparejPCTBuffer(dc.getDrawableWidth(), dc.getDrawableHeight());
// inject gl if neccessary
if (this.lastGL != gl) {
Util.injectExternalGL(canvas, gl);
this.lastGL = gl;
}
}
/**
* Called by WorldWind to refresh this layer.
*/
@Override
protected void doRender(DrawContext dc) {
this.beginDraw(dc);

// get the eye point of WW, to set the camera in jPCT
// so that jpct's camera go with ww's eye point
Vec4 eyeLoc = dc.getView().getEyePoint();
this.world.getCamera().setPosition(ww2jpct(eyeLoc));
this.world.getCamera().lookAt(new SimpleVector(0, 0, 0));

// save current gl settings before change it
dc.getView().pushReferenceCenter(dc, eyeLoc);

// jPCT draw its world with the given gl
this.repaint();

// force jPCT to draw on WW's gl.
Util.forceDraw(canvas);

    // restore last gl settings
dc.getView().popReferenceCenter(dc);
this.endDraw(dc);
}

// resets opengl state
protected void endDraw(DrawContext dc) {
GL2 gl = (GL2) dc.getGL();

gl.glMatrixPopEXT(GL2.GL_TEXTURE);
gl.glMatrixPopEXT(GL2.GL_PROJECTION);
gl.glMatrixPopEXT(GL2.GL_MODELVIEW);

gl.glMatrixMode(GL2.GL_TEXTURE);
gl.glPopMatrix();
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glPopMatrix();
gl.glMatrixMode(GL2.GL_MODELVIEW);//|GL2.GL_PROJECTION|GL2.GL_TEXTURE);
gl.glPopMatrix();

gl.glPopAttrib();
}

/**
* convert WorldWind's Vec4 to jPCT's SimpleVector.
*
* @param x
* @param y
* @param z
* @return
*/
public static SimpleVector ww2jpct(double x, double y, double z) {
return new SimpleVector((float) x, (float) -y, (float) -z);
}

/**
* convert WorldWind's Vec4 to jPCT's SimpleVector.
*
* @param x
* @param y
* @param z
* @return
*/
public static SimpleVector ww2jpct(Vec4 vec) {
return new SimpleVector((float) vec.x, (float) -vec.y, (float) -vec.z);
}

/**
* move the object to the given position, not delta.
*
* @param obj
*            the object to me moved
* @param sv
*            the target position
*/
public static void setObject3DPosition(Object3D obj, SimpleVector sv) {
method: do {
if (sv == null || obj == null) {
Log.e("The input param sv or obj is null.");
break method;
}
SimpleVector cur = obj.getTranslation();
obj.translate(sv.calcSub(cur));
} while (false);
}
/**
* move the object to the given position, not delta.
* x,y,z is jPCT coordinate.
* @param obj
* @param x
* @param y
* @param z
*/
public static void setObject3DPosition(Object3D obj, float x, float y,
float z) {
method: do {
if (obj == null) {
Log.e("The input param obj is null.");
break method;
}
SimpleVector sv = new SimpleVector(x, y, z);
SimpleVector cur = obj.getTranslation();
obj.translate(sv.calcSub(cur));
} while (false);
}

public static Vec4 jpct2wwPoint(float x, float y, float z) {
return new Vec4(x, -y, -z);
}

public static Vec4 jpct2wwPoint(SimpleVector sv) {
Vec4 result = null;
method: do {
if (sv == null) {
Log.e("The input param sv is null.");
break method;
}
result = new Vec4(sv.x, -sv.y, -sv.z);
} while (false);
return result;
}

public static SimpleVector ww2jpct(Position position) {
SimpleVector result = null;
method: do {
if (position == null) {
Log.e("The input param position is null.");
break method;
}
Vec4 vec = D3Man.getInstance().position2Point(position);
result = new SimpleVector((float) vec.x, (float) -vec.y,
(float) -vec.z);
} while (false);
return result;
}

public static Position jpct2wwPosition(float x, float y, float z) {
return D3Man.getInstance().point2Position(x, -y, -z);
}

public static Position jpct2wwPosition(SimpleVector sv) {
Position result = null;
method: do {
if (sv == null) {
Log.e("The input param sv is null.");
break method;
}
result = D3Man.getInstance().point2Position(sv.x, -sv.y, -sv.z);
} while (false);
return result;
}



/**
* force this layer to redraw components inside it.
*/
public void repaint() {
// buffer.clear(new Color(0.0f,0.0f,0.0f,1.0f));
world.renderScene(buffer);
world.draw(buffer);
buffer.update();
buffer.displayGLOnly();
canvas.repaint();
}
}

As we can see, the Object3d box(.3ds if loaded, or a primitive box) is placed at (0, 20, 16000) with WW's latitude-longitude-elevation coordinate.

To debug the layer, i add a BeanShell script engine so that i can execute script's lively.
When i execute the following script to locate the 3d object, i can not directly see it.
In fact, it is blocked by other layers. Event when i put the jPCTLayer at the top or last of the layers' list, it is blocked.
When i unselect the blocker layer, make it invisible, i can see the jPCT's 3d object, rotating.
Code: [Select]
import gov.nasa.worldwind.geom.Position;
import java.util.ArrayList;
import java.util.List;
import org.gbzh.jsapi.tts.AudioData;
import org.gbzh.jsapi.tts.SimplePlayer;
import org.gbzh.jsapi.tts.SpeechEngine;
import org.aoe.det.ww.d3man.ww.KMLLayerMan;


wwFunc(){
  //go to given position
  public void GoTo(double latitude, double longitude, double elevation){
    Position position = Position.fromDegrees(latitude, longitude, elevation);
    worldwindow.getView().goTo(position, elevation);
  }
  return this;
}
ww = wwFunc();

ww.GoTo(0.0, 20.0, 16020.0);

I don't know why the jPCT layer is blocked by others.

And the WW dose not function well with jPCT layer.
When the cursor is on the WW's earth globe, it will display the current lat-lon-elev data.
But when the jPCT layer is loaded, it only displays "Off", which means the cursor is not on the globe.
Another problem is the navigator view display nothing but white square.

The following code shows how i force jPCT to draw on WW's GL. Note that, it is in the package com.threed.jpct, where we can access the JOGLCanvas and it's package-level methods.
Code: [Select]
package com.threed.jpct;

import java.awt.Canvas;

import javax.media.opengl.GL;

public class Util {
public static void forceDraw(Canvas canvas){
JOGLCanvas jc = (JOGLCanvas)canvas;
jc.display(null);
}

public static void injectExternalGL(Canvas canvas, GL gl){
JOGLCanvas jc = (JOGLCanvas)canvas;
jc.injectExternalGL(gl);
}
}


I'm trying to find the reason, but without jPCT's source, its really painful.

I'll go on until succeed or give up.

PS: The missed classes such as Log and Resource is simple. Log outputs log information and Resource fetches files from a given directory.

2
Bugs / jPCT dose not support jogl 2.1.5
« on: August 27, 2015, 05:16:40 am »
Since jogl 2.1.5 have many refactors on GL* classes, jPCT' glfacade can not  find the old classes in old version jogl.
Actually, it is a simple task to update jPCT and glfacade for new jogl version.

Would u plz modify them and release new versions.

Or you may make them open source, i can do that quickly:)

Forgive my Chinglish:)

Pages: [1]