The question about billboarding

Started by gamenewer, December 28, 2014, 08:34:38 AM

Previous topic - Next topic

gamenewer

Hello Egon, I  use a single plane  to show tree in my game, I can place it on the "ground" when  not set it billboarding , but when I set it billboarding, It float abover the "ground", and I can't place it  on the "ground", It  seems out of contral ( I try used translate function). Could you help me to resove this question?  Thanks a lot ! :)

Lobby

I think the problem is that objects with billboarding won't keep their Y-Axis parallel to the Y-axis in world coordinates. A solution would be to disable billboarding on the object and to calculate the the rotation yourself. It would be nice if this functionality could be integrated directly into jPCT because it's often needed for things like trees :) .

gamenewer

Thank you Lobby, How to  calculate the the rotation? Could you give me some example code ? Thanks !

EgonOlsen

Yes, billboards will face the camera on all axes. You can't lock one. If you need that, you have to calculate it yourself somehow. If you keep track of the camera's rotation around y, it should be pretty easy to do. Or just scrap billboarded planes and use some slightly more complex mesh instead.

gamenewer

Hi Egon,I have no idea,  could you give me some example code? Thank you very much !

EgonOlsen

I don't have any. It depends on your application and how you setup the camera. If you can somehow keep track of or calculate the camera's rotation around y, all you might have to do is to apply the inverse rotation to your trees. But again, it depends on your scene and it might look crappy anyway when you come close to the trees.
Personally, i would use some more complex, real 3d models instead that don't need this treatment.

gamenewer


Lobby

Here, have a little sample that shows how you might calculate the rotation.

package info.flowersoft.collisionproblemtext;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import com.threed.jpct.Camera;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.GLSLShader;
import com.threed.jpct.IRenderHook;
import com.threed.jpct.Light;
import com.threed.jpct.Object3D;
import com.threed.jpct.RGBColor;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.World;
import com.threed.jpct.util.ExtendedPrimitives;

import android.support.v7.app.ActionBarActivity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;

public class MainActivity extends ActionBarActivity {

GLSurfaceView view;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

getSupportActionBar().hide();

view = new GLSurfaceView(this);
view.setEGLContextClientVersion(2);

view.setRenderer(new GLSurfaceView.Renderer() {

private World world;
private FrameBuffer buffer;

private Object3D sprite;

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
world = new World();
world.getCamera().moveCamera(Camera.CAMERA_MOVEIN, 1);
world.getCamera().setOrientation(new SimpleVector(0, 1, 1), new SimpleVector(0, -1, 1));
world.getCamera().moveCamera(Camera.CAMERA_MOVEOUT, 10);
world.getCamera().moveCamera(Camera.CAMERA_MOVELEFT, 5);

Light light = new Light(world);
light.setPosition(new SimpleVector(0, -50, 0));

Object3D plane = ExtendedPrimitives.createPlane(10);
plane.rotateZ(0.01f);
world.addObject(plane);

sprite = ExtendedPrimitives.createSprite();
sprite.setAdditionalColor(RGBColor.BLACK);
sprite.setLighting(Object3D.LIGHTING_NO_LIGHTS);
sprite.scale(2);
sprite.setBillboarding(Object3D.BILLBOARDING_DISABLED);
sprite.setRenderHook(new IRenderHook() {

@Override
public void setTransparency(float transparency) {
}

@Override
public void setCurrentShader(GLSLShader shader) {
}

@Override
public void setCurrentObject3D(Object3D obj) {
SimpleVector dir = world.getCamera().getPosition().calcSub(obj.getTransformedCenter());
dir.y = 0;
dir = dir.normalize();
dir.scalarMul(-1);
SimpleVector up = new SimpleVector(0, -1, 0);
obj.setOrientation(dir, up);
}

@Override
public boolean repeatRendering() {
return false;
}

@Override
public void onDispose() {
}

@Override
public void beforeRendering(int polyID) {
}

@Override
public void afterRendering(int polyID) {
}
});
world.addObject(sprite);
}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
buffer = new FrameBuffer(width, height);
}

@Override
public void onDrawFrame(GL10 gl) {
world.getCamera().moveCamera(Camera.CAMERA_MOVERIGHT, 0.005f);

buffer.clear();
world.renderScene(buffer);
world.draw(buffer);
buffer.display();
}
});

setContentView(view);
}
}

gamenewer

#8
Thank you Lobby, I use

                  SimpleVector dir = world.getCamera().getPosition().calcSub(obj.getTransformedCenter());
                  dir.y = 0;
                  dir = dir.normalize();
                  dir.scalarMul(-1);
                  SimpleVector up = new SimpleVector(0, -1, 0);
                  obj.setOrientation(dir, up);

in ondrawframe, but it seems no effect , why? thanks


Does your method  must set camera in special ? my camera is movement in my game.

Lobby

A special camera set shouldn't be needed, but the camera shouldn't look at your object from above.

What do you mean by "seems no effect"? Don't you see the object anymore or doesn't it rotate correctly?

If you can't see the object anymore maybe your object is flat and is rotated so that it's absolutely flat for the camera. Then a rotation of the object around Y-Axis may help.

If it doesn't rotate correctly check that you don't enable billboarding anymore, because it would override our own calculations.

gamenewer

#10
I mean the object  is't  rotate correctly. it seems not rotate. The object is not enalbe billboarding. I'm sorry for my poor english :)

If object must setRenderHook ?  I only calculat in ondrawframe .

Lobby

I just use the RenderHook for convenience. It shouldn't make a differece whether doing it in onDrawFrame oder within the hook...

Maybe you can test it with using a RenderHook. If this also doesn't work you may create a little sample project that shows the probem.

gamenewer

Thank you Lobby, I will try it and tell you the result  :)

gamenewer

Hi Lobby, I use your example , it works  ok. I  will check if  there is something wrong in my code, Thank you very much ! :)