collision with Bones

Started by subhalakshmi27, January 12, 2012, 12:05:41 PM

Previous topic - Next topic

subhalakshmi27

Hi All,

In normal 3D object in World space, following collision detection code worked.

sphere.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);
            sphere.addCollisionListener(new CollisionListener() {
               
               @Override
               public boolean requiresPolygonIDs() {
                  // TODO Auto-generated method stub
                  return false;
               }
               
               @Override
               public void collision(CollisionEvent arg0) {
                  Log.i("HelloWorldJPCT", "Sphere collision");
                  
               }
            });

When I tried the collision detection in Bones sample code , I never got any log message, Following is the code

ninjas.get(0).get(0).setCollisionMode(Object3D.COLLISION_CHECK_SELF);
      ninjas.get(0).get(0).addCollisionListener(new CollisionListener() {
         
         @Override
         public boolean requiresPolygonIDs() {
            // TODO Auto-generated method stub
            return false;
         }
         
         @Override
         public void collision(CollisionEvent ce) {
            // TODO Auto-generated method stub
            Log.i("app", "On collision");
            
         }
      });

Please let me know if I am missing something.

Regards,
Subha

raft

Bones does not do/change anything aboout collision detection. To be sure, I did a quick test by modifying collsion detection sample in wiki. added the lines below. collision detection worked and collision events are generated.

I'm not sure what's wrong with your sample. maybe it's the scaling of objects?



cube = BonesIO.loadGroup(new FileInputStream("ninja.group.bones")).get(0);
cube.scale(1f/10);
cube.translate(-50, -300, -50);

cube.addCollisionListener(new CollisionListener() {
@Override
public boolean requiresPolygonIDs() {
return false;
}

@Override
public void collision(CollisionEvent ce) {
System.out.println("collision");
}
});




subhalakshmi27

Hi Raft,

Sorry I forgot to mention this before, I am checking collision with bones in Android (JPCT-AE). I will check again what you have mentioned. Does Android engine can have an impact in Collision detection with bones  ::)?

Regards,
Subha

raft


subhalakshmi27

Hi Raft,

I tried again, but no luck. I am attaching the source code.
Previously in JPCT-AE forum, when the collision didn't work, One suggestion was given to make the screen as full screen. I did the same in this project also.

<activity
            android:label="@string/app_name"
            android:name=".BlendprojectActivity"
            android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

Do I need to post the question in JPCT-AE forum also ? I need the collision as I am trying to detect if the user has touched any specific area in animation.  :(

Thanks in Advance.

Regards,
Subha

[attachment deleted by admin]

raft

I can't see anything in your code which will trigger collision.

Below is a sample. It also demonstrates that model's animated shape is used in collision tests.


package bones.samples.android;

import glfont.GLFont;

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 raft.jpct.bones.Animated3D;
import raft.jpct.bones.AnimatedGroup;
import raft.jpct.bones.BonesIO;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.os.PowerManager;

import com.threed.jpct.Camera;
import com.threed.jpct.CollisionEvent;
import com.threed.jpct.CollisionListener;
import com.threed.jpct.Config;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.Light;
import com.threed.jpct.Logger;
import com.threed.jpct.Object3D;
import com.threed.jpct.Primitives;
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;

/**
*
* @author  hakan eryargi (r a f t)
*/
public class CollisionTestActivity extends Activity {

private static final int GRANULARITY = 25;

private GLSurfaceView mGLView;
private final MyRenderer renderer = new MyRenderer();
private World world = null;

private AnimatedGroup ninja;
private Object3D cube;

private long frameTime = System.currentTimeMillis();
private long aggregatedTime = 0;

private String blitText;
private long blitCountDown = 0;

private PowerManager.WakeLock wakeLock;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

mGLView = new GLSurfaceView(getApplication());
setContentView(mGLView);

mGLView.setEGLConfigChooser(new GLSurfaceView.EGLConfigChooser() {
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];
}
});

mGLView.setRenderer(renderer);

if (world != null)
return;

world = new World();

cube = Primitives.getBox(10, 1);
cube.translate(300, -100, 0);
cube.setCollisionMode(Object3D.COLLISION_CHECK_SELF);
world.addObject(cube);

try {
Resources res = getResources();
ninja = BonesIO.loadGroup(res.openRawResource(R.raw.ninja));
ninja.get(0).setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);
ninja.addToWorld(world);

ninja.get(0).addCollisionListener(new CollisionListener() {

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

@Override
public void collision(CollisionEvent ce) {
System.out.println("collided");
cube.translate(300, 0, 0);

blitText = "Collided";
blitCountDown = 500;
}
});

} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}

world.buildAllObjects();

world.setAmbientLight(127, 127, 127);
world.buildAllObjects();

new Light(world).setPosition(new SimpleVector(0, -400, 120));

Camera camera = world.getCamera();
camera.setPosition(0, -100, 500);
camera.lookAt(new SimpleVector(0, -100, 0));
camera.moveCamera(Camera.CAMERA_MOVERIGHT, -50);

PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "Collision-Demo");
}

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

if (wakeLock.isHeld())
wakeLock.release();
}

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

if (!wakeLock.isHeld())
wakeLock.acquire();
}

class MyRenderer implements GLSurfaceView.Renderer {

private SimpleVector ellipsoid = new SimpleVector(10, 10, 10);
private SimpleVector translation = new SimpleVector(-5, 0, 0);

private FrameBuffer frameBuffer = null;

private GLFont glFont;

private float animationIndex = 0;

public MyRenderer() {
Config.maxPolysVisible = 5000;
Config.farPlane = 1500;
}

@Override
public void onSurfaceChanged(GL10 gl, int w, int h) {
Logger.log("onSurfaceChanged");
if (frameBuffer != null) {
frameBuffer.dispose();
}
frameBuffer = new FrameBuffer(gl, w, h);
}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
Logger.log("onSurfaceCreated");

TextureManager.getInstance().flush();
Resources res = getResources();

Texture texture = new Texture(res.openRawResource(R.raw.ninja_texture));
texture.keepPixelData(true);
TextureManager.getInstance().addTexture("ninja", texture);

for (Animated3D a : ninja)
a.setTexture("ninja");

Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setTypeface(Typeface.create((String)null, Typeface.BOLD));

paint.setTextSize(16);
glFont = new GLFont(paint);

paint.setTextSize(50);
}

@Override
public void onDrawFrame(GL10 gl) {
if (frameBuffer == null)
return;


long now = System.currentTimeMillis();
aggregatedTime += (now - frameTime);
frameTime = now;

if (aggregatedTime > 1000) {
aggregatedTime = 0;
}


while (aggregatedTime > GRANULARITY) {
aggregatedTime -= GRANULARITY;

animationIndex += 0.02f;
while (animationIndex > 1)
animationIndex -= 1;

ninja.animateSkin(animationIndex, 20);

cube.checkForCollisionEllipsoid(translation, ellipsoid, 1);
cube.translate(translation);

if (cube.getTranslation().x < -100) {
cube.translate(400, 0, 0);

blitText = "Missed";
blitCountDown = 500;
}

blitCountDown -= GRANULARITY;
}


frameBuffer.clear();
world.renderScene(frameBuffer);
world.draw(frameBuffer);

if (blitCountDown > 0) {
glFont.blitString(frameBuffer, blitText, 10, 30, 10, RGBColor.WHITE);
}

frameBuffer.display();
}
}
}

subhalakshmi27

Hi Raft,

I am checking if the user touches 3D model. If the 3D model is been picked (compatible way for http://www.jpct.net/wiki/index.php/Picking)

Here the user touch is the collision. In normal Object3D, if user touches the 3D model, CollisionListener (public void collision(CollisionEvent arg0)) was called. In Bones on user touch collision function was never called.

Regards,
Subha




raft

there is no such thing in your code. neither touch events, nor World.checkCollisionXX or World.calcMinDistanceXX calls.

subhalakshmi27

Hi Raft,

I am sorry. I modified the code, but forgot to attach the same.

In normal 3D object I checked both collision listener and Touch Event, both worked. I applied the same logic in bones example. I am attaching normal 3D code (HelloWorld.java) when the user touches the object in onTouchEvent, by reproject2D3DWS and CalcMinDistance, the object which has been clicked was found.
Similarly by addcollisionlistener, collision was detected. Both the log message was seen when user touch event happened.

Sorry for troubling you.

Thanks and Regards,
Subha

[attachment deleted by admin]

raft

sorry, this forum is not a code-review service. i've shown you that Bones does not alter collision code and even wrote a sample. i'm sure you can handle the rest from here. i suggest you starting from the working HelloWorld sample, and replace the cube with ninja.

btw, the HelloWorld sample you had sent is not working but the one in wiki page does

subhalakshmi27

Hi Raft,

I understood the concept now. In Bones example Animated Group is added to World.

For collision to work, along with this Animate3D object has to be added to the world. I was adding the listener without adding the object to the world, I assumed that adding the animated group should work for collision.

world.addObject(Object3D). Now I am able to detect the colloision now.

private AnimatedGroup character;
Object3D char_main = null;

character = BonesIO.loadGroup(res.openRawResource(R.raw.ninja));

char_main = character.get(0);
world.addObject(character.get(0));
character.addToWorld(world);

Thanks a lot for your help.

Regards,
Subha

raft

Not really true. as Bones is not part of core jPCT, you can not add an AnimatedGroup to a World. AnimatedGroup.addToWorld(..) method is just a shortcut to add all Animated3D's in that group to world.

Anyway, I'm glad you solved the problem