Making sound when objects hit

I have a program where you move blocks around. I want to make it so that when they hit each other and the floor they make sound. I tried using DynamicPhysicsNode with the blocks, box, attached. But it used a bounding box and was unreal. Then I found ContactCallback I tried that and the blocks kept making contact with the floor and playing the sound over and over again. Gets very annoying :P  I tried the code below to stop that but it did not work. It is based on TestGenerateGeometry for the physics and HelloIntersection for the sound.



staticNode.setName( "floor");

Vector3f t = new Vector3f();

c.getContactVelocity(t);

if (t != new Vector3f(0,0,0))

if (!c.getNode1().getName().equals("floor") || !c.getNode2().getName().equals("floor"))



Any ideas? Has anyone done this before?

Thanks In Advance

First, a basic thing in java: the following condition is always true!

cyberknight said:

if (t != new Vector3f(0,0,0))


Second, you should not use ContactCallback but the collision handler with an input handler (see TestBasicRepresentation).

I was using code like this a MultiShufflePuck:


        input.addAction( new InputAction() {
            public void performAction( InputActionEvent evt ) {
                ContactInfo info = (ContactInfo) evt.getTriggerData();
                info.getContactVelocity( contactVelocity );
                float vel = contactVelocity.length();
                // check that the velocity the items hit is large enough to make a sound
                if ( vel > 10 ) {
                    if ( isPuck( info.getNode1() ) || isPuck( info.getNode2() ) {
                        sample.setVolume( Math.min( vel/100, 1 ) );
                        sample.getTracker().setToTrack( info.getNode1() );
                        sample.getTracker().checkTrackAudible( camera.getLocation() );
                        sample.play();
                    }
                }
            }
        }, getPhysicsSpace().getCollisionEventHandler(), false );


While this used game specific entities to determine the result of 'isPuck' and uses game specific sound classes. But you should grab the idea.

What are you using contactVelocity for? And what is it?

Thanks for your help again  :smiley:

The contact velocity is the sum of velocities of the object in the direction of the contact normal. I'm using it to determine the 'power' of the hit to set the volume of the sound. (but not it's not really the force applied, as it disregards the mass)

OK, I copied the SyntheticButton / InputAction thing, and had a few issues with it.


  1. included static phyics node collisions (easy - return if node1 || node2 instanceof staticphysicsnode)
  2. includes self collisions (node1 == node2) - how is this possible



    and


  3. does not trigger when 2 dynamic physics nodes connect (the ball pushes the box… but nothing in the console).



    the update(float) method on the input handler is being straight after physicsSpace.update(float)



    I don't mind having to do the extra filters, but I do mind that I cant get two different nodes (eg - trigger on collision). any ideas?
ebola said:

3) does not trigger when 2 dynamic physics nodes connect (the ball pushes the box... but nothing in the console).

That's exactly what this line should filter out:

if ( vel > 10 ) {


so 'touching' could go into an else block.

node1 == node2 should not happen unless you use PhysicsSpace.pick.

erm… the input action is custom, the I just copied the mechanism for hooking it up.



I want events to happen on contact with a particular node. it slaves to a hash map & call listeners.



it looks something like this:


if (node1 instanceof StaticPhysicsNode || node2 instanceof StaticPhysicsNode) return;
if (node1 == node2) { System.out.println("node1 == node2"); return; }
System.out.println("here");
if (actions.containsKey(node1)) actions.get(node1).execute(node1, node2);
if (actions.containsKey(node2)) actions.get(node2).execute(node2, node1);


pretty simple - my console is filled with ==, but never has a sinle "here". I'll have a poke around tomorrow night, along with a slight re-write (results to follow).

I cannot reproduce your problems here. This code never prints "This should not happen!" and it prints "two dynamic " all the time when you push one of the objects with the other one…


package com.jmetest.physics;

import com.jme.input.action.InputAction;
import com.jme.input.action.InputActionEvent;
import com.jmex.physics.contact.ContactInfo;

public class TestCollisionHandler extends TestGenerateGeometry {
    @Override
    protected void simpleInitGame() {
        super.simpleInitGame();

        input.addAction( new InputAction() {
            private int i;
            public void performAction( InputActionEvent evt ) {
                ContactInfo info = (ContactInfo) evt.getTriggerData();
                if ( info.getNode1() == info.getNode2() )
                {
                    System.out.println( "This should not happen!" );
                }
                if ( !info.getNode1().isStatic() && !info.getNode2().isStatic() )
                {
                    System.out.println( "two dynamic " + i++ );
                }
            }
        }, getPhysicsSpace().getCollisionEventHandler(), false );
    }

    public static void main( String[] args ) {
        new TestCollisionHandler().start();
    }
}

awwww crap… I hate retractions.



node1 = ci.getNode1();

node2 = ci.getNode1();



umm… crap. No, it all handles just fine… now…



I don't get it. 3am is usually so productive…  :wink: