Collision Detection failing me!

Ok so here is the scenario!

I have an enemy object which is moving back and forth thanks to a lovely spatial transformer.

I then have a tower which is shooting a nasty looking particle at the location of the enemy.

I am trying to detect if any of the particles hit the enemy, and if they do decrease its energy accordingly.

So my tower code (which contains the particle info, and the collision detection) is this :

[code]
package Defence;

import Enemys.Buster;
import Tools.ModelLoader;

import com.jme.bounding.BoundingBox;
import com.jme.bounding.BoundingSphere;
import com.jme.bounding.CollisionTree;
import com.jme.bounding.CollisionTreeManager;
import com.jme.intersection.CollisionResults;
import com.jme.intersection.TriangleCollisionResults;
import com.jme.math.FastMath;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.scene.Line;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.state.BlendState;
import com.jme.scene.state.ZBufferState;
import com.jmex.effects.particles.ParticleFactory;
import com.jmex.effects.particles.ParticleLines;

public class DTower extends Node {

   private Spatial model;
   float power;
   float speed;
   boolean freezable;
   int id;
    private ParticleLines pLines;
    private Vector3f currentPos = new Vector3f();
    public Vector3f newPos = new Vector3f();
    Renderer renderer;
    Vector3f directionAttack;
    Node rootNode;
    Buster enemy;
    CollisionResults results;
   
   public DTower(int id,float power, float speed,boolean freezable,Vector3f directionAttack,Spatial model,Renderer renderer, Node rootNode,Buster enemy){
      
      setModel(model);
      this.id=id;
      this.power=power;
      this.speed=speed;
      this.freezable=freezable;
      this.renderer=renderer;
      this.directionAttack=directionAttack;
      this.rootNode=rootNode;
      this.enemy=enemy;
      setupAttack();
      
      
   }
   
   public Vector3f getDirectionAttack() {
      return directionAttack;
   }

   public void setDirectionAttack(Vector3f directionAttack) {
      this.directionAttack = directionAttack;
   }

   public float getPower() {
      return power;
   }

   public void setPower(float power) {
      this.power = power;
   }

   public float getSpeed() {
      return speed;
   }

   public void setSpeed(float speed) {
      this.speed = speed;
   }

   public boolean isFreezable() {
      return freezable;
   }

   public void setFreezable(boolean freezable) {
      this.freezable = freezable;
   }

   public int getId() {
      return id;
   }

   public void setId(int id) {
      this.id = id;
   }


   
    public void setModel(Spatial model) {
           this.detachChild(this.model);
           this.model = model;
           this.attachChild(this.model);
       }

   private void setupAttack(){
      
       pLines = ParticleFactory.buildLineParticles("particles", 300);
           pLines.setLineWidth(3);
           pLines.setMode(Line.Mode.Segments);
           pLines.setAntialiased(true);
           pLines.setParticleOrientation(FastMath.HALF_PI); // Particle Lines
                                                           // are horizontal by
                                                           // default, this
                                                           // turns it vertical
          
          
           pLines.setEmissionDirection(directionAttack);
           //pLines.setLocalRotation(enemy.getLocalRotation());
          pLines.setVelocityAligned(true);
         //  pLines.setParticleOrientation(250);
           pLines.setOriginOffset(new Vector3f(1280,100,1280));
           pLines.setInitialVelocity(0.007f);
           pLines.setStartSize(4f);
           pLines.setEndSize(1.5f);
           pLines.setMinimumLifeTime(500f);
           pLines.setMaximumLifeTime(2800f);
           pLines.setParticleSpinSpeed(3 * FastMath.PI); // rotate 3pi times (1.5 rotations) per second
           pLines.setStartColor(new ColorRGBA(1, 0, 0, 1));
           pLines.setEndColor(new ColorRGBA(0, 1, 0, 0));
           pLines.setMaximumAngle(360f * FastMath.DEG_TO_RAD);
           pLines.getParticleController().setControlFlow(false);
          
           pLines.warmUp(120);

           BlendState as1 = renderer.createBlendState();
           as1.setBlendEnabled(true);
           as1.setSourceFunction(BlendState.SourceFunction.SourceAlpha);
           as1.setDestinationFunction(BlendState.DestinationFunction.One);
           as1.setEnabled(true);
           pLines.setRenderState(as1);

           ZBufferState zstate = renderer.createZBufferState();
           zstate.setEnabled(false);
           pLines.setRenderState(zstate);

           pLines.setModelBound(new BoundingSphere());
           pLines.updateModelBound();

          
           CollisionTreeManager.getInstance().setTreeType(CollisionTree.Type.AABB);
           results = new TriangleCollisionResults();
          
           rootNode.attachChild(pLines);
      
   }

   public Vector3f getCurrentPos() {
      return currentPos;
   }

   public void setCurrentPos(Vector3f currentPos) {
      this.currentPos = currentPos;
   }

   public Vector3f getNewPos() {
      return newPos;
   }

   public void setNewPos(Vector3f newPos) {
      this.newPos = newPos;
   }
   
   public void fire(float tpf){
      //CollisionResults results = null;
      
      
      
      if ((int) currentPos.x == (int) newPos.x
                && (int) currentPos.y == (int) newPos.y
                && (int) currentPos.z == (int) newPos.z) {
            newPos.x = directionAttack.x;
            newPos.y = directionAttack.y;
            newPos.z = directionAttack.z;
        }

      float frameRate = tpf / 2;
      System.out.println("Frame rate is:"+frameRate);
        currentPos.x -= (currentPos.x - newPos.x) / frameRate;
        currentPos.y -= (currentPos.y - newPos.y) / frameRate;
        currentPos.z -= (currentPos.z - newPos.z) / frameRate;

        pLines.setOriginOffset(currentPos);

results.clear();
      
      pLines.findCollisions(enemy, results);
        
         if (results.getNumber() > 0) {
           
                               
                   System.out.println("Hello Collision");
             
                           }
      
}
   
}
[/code]

However no Hello Collisions are ever printed. Now this MAY be because the particles are slightly behind the enemy model, which is moving quite fast - but I would expect some collisions when the model double backs on itself and goes back and forth?

The movement of the enemy node is :

[code]

private void setEnemyMovement(Buster enemy){
      
      Vector3f[] cameraPoints = new Vector3f[]{
               new Vector3f(enemy.getLocalTranslation()),
               new Vector3f(enemy.getLocalTranslation().x,enemy.getLocalTranslation().y,(enemy.getLocalTranslation().z+500f)),
           };
           // Create a path for the camera.
           BezierCurve bc = new BezierCurve("camera path", cameraPoints);
           // Create a camera node to move along that path.
        
           // Create a curve controller to move the CameraNode along the path
           CurveController cc = new CurveController(bc, enemy);
           // Cycle the animation.
           cc.setRepeatType(Controller.RT_CYCLE);
           // Slow down the curve controller a bit
           cc.setSpeed(.25f);
           enemy.addController(cc);
   }

[/code]

Even when making the enemy model move very slowly, no collisions are ever reported.

It may be because the code goes, move enemy, update particles to be aiming at the current position of enemy, then the enemy moves again.

If this is the case - how do i solve it!

What could be the problem!

Why don't you try stopping the enemy to see if there is any collisions at all? Just make it obvious that it is colliding yet not working then see what happens.

hmm i don't think particles will generate collisions since the single particles don't have BoundingBoxes, i might be off tho.



Do you really want to shoot particles at the enemy?

Maybe you could achieve a similar visual effect with shooting a textured box at the enemy, with that collission detection will be much easier i think.



Or shoot both together, an (invisible) box for collision detection and particles for the visual stimulation :slight_smile:

if particles couldnt detect collisions why are the functions there for use in the object!?



I could do a textured box, but bullets tend to be not box shapped, i was really looking for the kinda effect where you see the bullet trace :



http://www.youtube.com/watch?v=UpJSS8G6_rU&feature=related



If you watch that, there is lots of bullet smoke, and bullet traces - this is what I am trying to recreate as machine gun fire.



Has anybody done this , or know how I could do it?

easiest would be a node with particles and a bullet

and then move that node

renegadeandy said:

Has anybody done this , or know how I could do it?

The answer may have slipped by you, so I'll repeat:
Core-Dump said:

Or shoot both together, an (invisible) box for collision detection and particles for the visual stimulation :)


I would expect particle collisions to be problematic to say the very least - especially with line particles!
The fact that particles inherit certain methods from one of their parent classes does not mean that all of those methods are reasonable to use. Particles are a rendering technique which is specifically tuned for performant rendering, not game logic.

It is generally best to see "what is on screen" and "what is happening to my game objects" as two distinct worlds, pretty much like MVC or similar patterns do.
I think when developing a game, or more abstract a "simulation of an interactive world", it is essential to understand a fundamental difference to our real world:
what's on screen is NOT what's actually going on - it is merely a user interface to visualize all the number crunching going on behind the scenes!
With that philosophy in mind, Core-Dump's idea is the most natural solution to your problem: just make an invisible box representing your missile in the "game logic world", and some particles and whatnot representing the same missile in "what's-on-screen world".

yes, make sure there is plenty of whatnot :slight_smile:

Ok - does anybody have an example of a Bullet Node which I can study i.e its movement towards an enemy or in a certain direction and the particle effect surrounding the bullet.

Dunno if this helps, but I do my bullets something like this (abridged version).  BTW, before the bullet is fired,  I use a Ray to calculate where the bullet is going to finish, rather than use the bullet itself for collision detection, so it may not be what you're looking for.



public final class Bullet extends Node {



private Vector3f move_dir;

private float max_dist;

private float dist = 0; // Dist travelled so far



public Bullet(Vector3f start, Vector3f end, float SPEED) {

  …

move_dir = end.subtract(start).normalize().mult(SPEED);

max_dist = end.subtract(start).length();



Cylinder s = new Cylinder("Bullet", 6, 6, RAD, 0.4f);



s.setModelBound(new BoundingSphere());

this.updateModelBound();

this.attachChild(s);



main.rootNode.attachChild(this);



this.updateGeometricState(0, true);

this.lookAt(end, Vector3f.UNIT_Y); // Point us at our target!



}



public void update(float interpolation) {

Vector3f act_dir = move_dir.mult(interpolation); // Actual movement offset

this.getLocalTranslation().addLocal(act_dir);

dist += act_dir.length();

if (dist > max_dist) {

this.removeFromParent();

} else {

this.updateGeometricState(interpolation, true);

}

}



}