Pong colision

I tried collision detection with "hasCollision" method on Sphere, but if the ball was too fast it would pass thru the walls without colliding… i so now i will use "findTrianglePick(Ray toTest, ArrayList<Integer> results)", but i don't get how the results are organized… since i don't know how the spatial data is organized either it would be difficult to just guess the correct way to get the triangle from this method. my idea to detect collision would be:



1: make a ray from the ball to the ball position + speed.

2: check for triangle intersections with the ray and all spatial

3: if no collisions,  move the ball to ball position + speed.

4: if collided, calculate the angle and direction of the first collision using the triangle points(don't know how to get the points)

5: calculate a new ray from the collision point to the collision point + new speed

6: go back to 2.



this method would do i guess… but since the results from "findTrianglePick" are a bunch of integers and the points of the triangles are 3 Vector3fs i don't know how to transform one result on another :confused:



thx in advance ;D

Well, the one thing I can tell you is that your new approach will not solve your original problem…





you need to test for cases where the ball has already passed through the wall, then 'back it up' if it has…





maybe this will help though, its my Picking util (I think it would be pretty easy to obtain the triangle normal, and use it for the 'reaction' direction)…



package com.tribaling.tildruin.shared.control;

import com.jme.input.MouseInput;
import com.jme.intersection.PickResults;
import com.jme.intersection.TrianglePickResults;
import com.jme.math.Ray;
import com.jme.math.Triangle;
import com.jme.math.Vector2f;
import com.jme.math.Vector3f;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.TriMesh;
import com.jme.system.DisplaySystem;

import java.awt.Point;
import java.util.ArrayList;



public class MousePicker {

    private String closestPickedName = null;
    private TriMesh savedMesh = null;
    private Spatial pickNode = null;      // Typically this will be the rootNode
    //
    private final PickResults pickResults = new TrianglePickResults();
    private final DisplaySystem display;
    //
    private final Ray ray = new Ray();
    private final Vector2f screenPos = new Vector2f();
    private final Vector2f cursorPosition = new Vector2f();
    private final Vector3f worldPickLocation = new Vector3f();
    private final Vector3f camLocation = new Vector3f();
    private final Vector3f tempWorldPick = new Vector3f();
    private final Vector3f[] tempTriVerticies = new Vector3f[ 3 ];
    private final Triangle pickedTriangle = new Triangle( new Vector3f(), new Vector3f(), new Vector3f() );
    private final Triangle tempTriangle = new Triangle( new Vector3f(), new Vector3f(), new Vector3f() );
    //
    private final ArrayList<String> pickedNames = new ArrayList();
    private final ArrayList<Integer> tempTriIndicies = new ArrayList();
    //
    private boolean objectWasPicked = false,  triangleWasPicked = false,  wasTriangleAccurate = false;
    private boolean useCanvas = false,  useSuppliedRay = false;
    //
    public MousePicker() {
        display = DisplaySystem.getDisplaySystem();
        useCanvas = false;
        pickResults.setCheckDistance( true );
    }

    public MousePicker( boolean useCanvas ) {
        this();

        this.useCanvas = useCanvas;
    }

    public MousePicker( boolean useCanvas, Spatial pickNode ) {
        this( useCanvas );

        setPickSpatial( pickNode );
    }

    public void setPickSpatial( Spatial spatial ) {
        pickNode = spatial;
    }

    public boolean checkMousePicks() {
        this.useSuppliedRay = false;
        return checkMousePicks( false );
    }

    public boolean checkMousePicks( boolean triangleAccurate ) {
        this.useSuppliedRay = false;
        return runPicker( triangleAccurate );
    }

    public boolean checkMousePicks( boolean triangleAccurate, Point cursorPosition ) {

        if( cursorPosition != null ){
            this.cursorPosition.set( cursorPosition.x, cursorPosition.y );
        }

        this.useSuppliedRay = false;
        return runPicker( triangleAccurate );
    }

    public boolean checkMousePicks( boolean triangleAccurate, final Ray suppliedRay ) {
        ray.set( suppliedRay );
        useSuppliedRay = true;

        return runPicker( triangleAccurate );
    }

    private boolean runPicker( boolean triangleAccurate ) {

        if( pickNode == null ){
            return false;
        }

        clearPickResults();
        wasTriangleAccurate = triangleAccurate;
        float shortestDist = Float.MAX_VALUE;

        if( !useSuppliedRay ){
            camLocation.set( DisplaySystem.getDisplaySystem().getRenderer().getCamera().getLocation() );

            if( useCanvas ){
                screenPos.set( cursorPosition );
            } else{
                screenPos.set( MouseInput.get().getXAbsolute(), MouseInput.get().getYAbsolute() );
            }

            try{
                display.getPickRay( screenPos, useCanvas, ray );
            } catch( Exception e ){
                return false;
            }
        } else{
            camLocation.set( ray.getOrigin() );
        }
       
        pickNode.findPick( ray, pickResults );

        if( pickResults.getNumber() <= 0 ){
            return false;
        }

        objectWasPicked = true;

        for( int i = 0; i < pickResults.getNumber(); i++ ){

            Node parent = pickResults.getPickData( i ).getTargetMesh().getParent();

            // itterate up through nodes while:
            // parent is not null AND parent has name AND parent does not equal pickNode
            while( parent.getParent() != null &&
                    parent.getParent().getName() != null &&
                    !parent.getParent().equals( pickNode ) ){
                parent = parent.getParent();
            }

            pickedNames.add( parent.getName() );

            if( triangleAccurate ){

                final TriMesh mesh = (TriMesh) pickResults.getPickData( i ).getTargetMesh();
               

                for( Integer triIndex : pickResults.getPickData( i ).getTargetTris() ) {
                   
                    // Get a single triangle and set the world transformations
                    mesh.getTriangle( triIndex, tempTriVerticies );
                    setTriVerticies( tempTriangle, tempTriVerticies, mesh );

                    if( ray.intersect( tempTriangle ) ){
                       
                        // get the exact location (in World coordinates) of the pick
                        triangleWasPicked = true;
                        ray.intersectWhere( tempTriangle, tempWorldPick );
                        final float tempDist = tempWorldPick.distance( camLocation );

                        // double check to make sure picked triangle is the closest possible triangle
                        // maybe not needed...
                        if( tempDist < shortestDist ){

                            // Set pickedTriangle and then save target mesh
                            setPickedTriangle( tempTriVerticies );
                            worldPickLocation.set( tempWorldPick );
                            closestPickedName = pickedNames.get( pickedNames.size() - 1 );
                            shortestDist = tempDist;
                            savedMesh = mesh;
                        }
                    }

                }  // End Triangle Accurate


            }

        }


        if( triangleAccurate ){
            return triangleWasPicked;
        }

        return objectWasPicked;
    }

    public boolean wasObjectPicked() {
        if( wasTriangleAccurate ){
            return triangleWasPicked;
        }

        return objectWasPicked;
    }

    public String getPickedObjectName() {

        if( wasTriangleAccurate ){
            if( closestPickedName != null ){
                return closestPickedName;
            } else{
                return "";
            }
        }

        try{
            return pickedNames.get( 0 );
        } catch( Exception e ){
            return "";
        }
    }

    public ArrayList<String> getAllPickedObjects() {
        return pickedNames;
    }

    public Triangle getPickedTriangle() {

        if( triangleWasPicked ){
            return pickedTriangle;
        }
        return null;
    }

    public TriMesh getSavedMesh() {
        return savedMesh;
    }

    public Vector3f getWorldPickLocation() {
        return worldPickLocation;
    }

    public void clearPickResults() {
        triangleWasPicked = false;
        objectWasPicked = false;
        savedMesh = null;
        closestPickedName = null;
       
        pickResults.clear();
        tempTriIndicies.clear();
        pickedNames.clear();
        worldPickLocation.set( 0, 0, 0 );
        pickedTriangle.get( 0 ).set( 0, 0, 0 );
        pickedTriangle.get( 1 ).set( 0, 0, 0 );
        pickedTriangle.get( 2 ).set( 0, 0, 0 );
    }

    // Save the triangle in terms of its original mesh (no transformations)
    private void setPickedTriangle( Vector3f[] verts ) {

        for( int i = 0; i < verts.length; ++i ){
            pickedTriangle.get( i ).setX( verts[i].getX() );
            pickedTriangle.get( i ).setY( verts[i].getY() );
            pickedTriangle.get( i ).setZ( verts[i].getZ() );
        }

        pickedTriangle.calculateCenter();

    }

    private void setTriVerticies( Triangle triangle, Vector3f[] verts, TriMesh mesh ) {
        for( int i = 0; i < verts.length; ++i ){
            mesh.localToWorld( verts[i], triangle.get( i ) );
        }

        triangle.calculateCenter();

    }
}

hmmm, quite big class to read… well i guess i will just use jMEPhysics for it, so i can even add gravity and stuff ;D



that would solve even problems that i still haven't faced



thx for the help

It is a long class but there are several 'goodies' in there I had to figure out, such as translating a triangle to world coordinates…



Yeah, using jME-Physics is a decent way to do things; can be a little tricky at times but the results are much more natural feeling.