JMEPhysics - JBullet updates in trunk / Bullet native in branch

…jjmontes looks forward to trying this soon…  :slight_smile:

Very nice!  Native bullet doesn't seem that slow when I do TestDominos.  :smiley:

A stable physics integration is so important for the engine.

Keep up the great work! :slight_smile:

Wanted to drop a quick update.  I've checked changes into both JMEPhysics branches.  Here's a quick rundown:



  Changes to jbullet-integration branch:

    -Fixed issues where scaled geometry shapes caused scaled translations as well.  (mostly with generated geometries)

    -Fixed force application issues.

    -Fixed mesh generation and collision issues.  Some mesh-mesh collision issues remain.

    -Removed support for 2x rotational axis joints until JBullet supports Hinge2 joints.



  Changes to bullet-native-integration branch:

    -Force application is wired up.

    -Node 'nudging' and velocity changes are now supported.



  Not much for the week, but they're both stabilizing a bit.  I look forward to some feedback

time to syc with svn again… Issues to follow (if there are any, I'm sure is perfect. All us devs are)

EDIT:: I work from head… my internet connection is flakey enough. I'll wait… sorry man


  Hi.

  I'm trying to use physics with JMonkeyEngine and I read about the JBullet implementation. Yet I could not find
build files for this implementation, so I created my own. Just in case you are interested in adding it.
Or may be I just overlooked it...

file: ant/module_physics.jbullet.xml



<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
  ~ Copyright (c) 2005-2006 jME Physics 2
  ~ All rights reserved.
  ~
  ~ Redistribution and use in source and binary forms, with or without
  ~ modification, are permitted provided that the following conditions are
  ~ met:
  ~
  ~  * Redistributions of source code must retain the above copyright
  ~    notice, this list of conditions and the following disclaimer.
  ~
  ~  * Redistributions in binary form must reproduce the above copyright
  ~    notice, this list of conditions and the following disclaimer in the
  ~    documentation and/or other materials provided with the distribution.
  ~
  ~  * Neither the name of 'jME Physics 2' nor the names of its contributors
  ~    may be used to endorse or promote products derived from this software
  ~    without specific prior written permission.
  ~
  ~ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  ~ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  ~ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  ~ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  ~ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  ~ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  ~ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  ~ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  ~ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  ~ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  ~ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  -->

<project name="module_physics.jbullet" default="compile.module.physics.jbullet" basedir="..">

    <property name="module.physics.jbullet.basedir" location="impl/jbullet"/>

    <property name="compiler.args.physics.jbullet" value="${compiler.args}"/>

    <property name="physics.jbullet.output.dir" value="${module.physics.jbullet.basedir}/classes"/>
    <property name="physics.jbullet.testoutput.dir" value="${module.physics.jbullet.basedir}/classes"/>

    <path id="physics.jbullet.module.bootclasspath">
        <!-- Paths to be included in compilation bootclasspath -->
    </path>

    <path id="physics.jbullet.module.classpath">
        <pathelement location="${physics.output.dir}"/>
        <pathelement location="${jme.output.dir}"/>
        <pathelement location="${module.physics.jbullet.basedir}/lib/jbullet.jar"/>
        <pathelement location="${module.physics.jbullet.basedir}/lib/stack-alloc.jar"/>
        <pathelement location="${module.physics.jbullet.basedir}/lib/vecmath.jar"/>
        <pathelement location="${module.physics.ode.basedir}/../../../jME/lib/lwjgl.jar"/>
        <pathelement location="${module.physics.ode.basedir}/../../../jME/lib/jorbis-0.0.12.jar"/>
        <pathelement location="${module.physics.ode.basedir}/../../../jME/lib/lwjgl_fmod3.jar"/>
        <path refid="library.junit.classpath"/>
    </path>


    <patternset id="excluded.from.module.physics.jbullet">
        <patternset refid="ignored.files"/>
    </patternset>

    <patternset id="excluded.from.compilation.physics.jbullet">
        <patternset refid="excluded.from.module.physics.jbullet"/>
    </patternset>

    <path id="physics.jbullet.module.sourcepath">
        <dirset dir="${module.physics.jbullet.basedir}">
            <include name="src"/>
        </dirset>
    </path>


    <target name="compile.module.physics.jbullet"
            depends="compile.module.physics.jbullet.production,compile.module.physics.jbullet.tests"
            description="Compile module physics.jbullet"/>

    <target name="compile.module.physics.jbullet.production" depends="compile.module.physics"
            description="Compile module physics.jbullet; production classes">
        <mkdir dir="${physics.jbullet.output.dir}"/>
        <javac destdir="${physics.jbullet.output.dir}" debug="${compiler.debug}" nowarn="${compiler.generate.no.warnings}"
               memoryMaximumSize="${compiler.max.memory}" fork="false">
            <compilerarg line="${compiler.args.physics.jbullet}"/>
            <bootclasspath refid="physics.jbullet.module.bootclasspath"/>
            <classpath refid="physics.jbullet.module.classpath"/>
            <src refid="physics.jbullet.module.sourcepath"/>
        </javac>

        <copy todir="${physics.jbullet.output.dir}">
            <fileset dir="${module.physics.jbullet.basedir}/src">
                <patternset refid="compiler.resources"/>
                <type type="file"/>
            </fileset>
        </copy>
    </target>

    <target name="release.module.physics.jbullet" depends="compile.module.physics.jbullet.production, release.module.physics">
        <jar jarfile="${physics.release.dir}/jme-physics-jbullet.jar" basedir="${physics.jbullet.output.dir}" update="yes"
             compress="true"
             includes="**"/>
        <mkdir dir="${physics.release.dir}/lib"/>
        <copy todir="${physics.release.dir}/lib">
            <fileset dir="${module.physics.jbullet.basedir}/lib">
                <include name="*.dll"/>
                <include name="*.so"/>
                <include name="*.*lib"/>
                <include name="*.jar"/>
            </fileset>
        </copy>
    </target>

    <target name="compile.module.physics.jbullet.tests" depends="compile.module.physics.jbullet.production"
            description="compile module physics.jbullet; test classes" unless="skip.tests"/>

    <target name="clean.module.physics.jbullet" description="cleanup module">
        <delete dir="${physics.jbullet.output.dir}"/>
        <delete dir="${physics.jbullet.testoutput.dir}"/>
    </target>

</project>



changes in file ant build.xml


*** build.xml   2009-10-16 00:55:10.000000000 -0400
--- build.txt   2009-10-16 00:54:06.000000000 -0400
***************
*** 36,42 ****
 
      <property file="ant/build.properties"/>
 
!     <property name="module.jme.basedir" location="../jME"/>
      <!-- Uncomment the following property if no tests compilation is needed -->
      <!--
     <property name="skip.tests" value="true"/>
--- 36,42 ----
 
      <property file="ant/build.properties"/>
 
!     <property name="module.jme.basedir" location="/home/toha/projects/jmonkey/jmonkeyengine-read-only/"/>
      <!-- Uncomment the following property if no tests compilation is needed -->
      <!--
     <property name="skip.tests" value="true"/>
***************
*** 86,102 ****
 
      <import file="${basedir}/ant/module_physics.ode.xml"/>
 
      <target name="init" description="Build initialization">
          <!-- Perform any build initialization in this target -->
          <echo>using jME base dir "${module.jme.basedir}"</echo>
      </target>
 
!     <target name="clean.all" depends="init, clean.module.physics, clean.module.physics.ode" description="cleanup all"/>
 
!     <target name="build.all" depends="init, compile.module.physics, compile.module.physics.ode"
              description="build all"/>
 
!     <target name="release.all" depends="init, release.module.physics, release.module.physics.ode"
              description="create jars">
          <zip zipfile="${physics.release.dir}/jme-physics.zip">
              <zipfileset dir="${physics.release.dir}">
--- 86,104 ----
 
      <import file="${basedir}/ant/module_physics.ode.xml"/>
 
+     <import file="${basedir}/ant/module_physics.jbullet.xml"/>
+
      <target name="init" description="Build initialization">
          <!-- Perform any build initialization in this target -->
          <echo>using jME base dir "${module.jme.basedir}"</echo>
      </target>
 
!     <target name="clean.all" depends="init, clean.module.physics, clean.module.physics.ode, clean.module.physics.jbullet" description="cleanup all"/>
 
!     <target name="build.all" depends="init, compile.module.physics, compile.module.physics.ode, compile.module.physics.jbullet"
              description="build all"/>
 
!     <target name="release.all" depends="init, release.module.physics, release.module.physics.ode, release.module.physics.jbullet"
              description="create jars">
          <zip zipfile="${physics.release.dir}/jme-physics.zip">
              <zipfileset dir="${physics.release.dir}">
***************
*** 108,111 ****
          </zip>
      </target>
 
! </project>
No newline at end of file
--- 110,113 ----
          </zip>
      </target>
 
! </project>

Oops! 



chuckle



I spend so much time in the IDE I forget about build files.  I've never actually BUILT any of the JME libraries . . . just run & test 'em.



My bad, Antony.  I'll take a look at the build file, make sure it's in line with what's in the rest of the library and either put it in or another suitable one.  Probably not RIGHT away, but likely before the weekend is over.  I prolly should put one in for the bullet physics native integration, too, eh?



Thanks for the post!



-Falken

Hm well funny, just tried to use the JBullet implementation, and now I have a slightly problem.



Just nothing happens O.o



It just seems to ignore setAngularVelocity completly, as well as addForce at


package Client;

import Client.MouseManager.MouseKey;
import Client.SolarSystem.Signature;
import Client.SolarSystem.SolarSystem;
import Client.SolarSystem.TargetAble;

import com.jme.input.KeyInput;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.scene.shape.Box;
import com.jmex.physics.DynamicPhysicsNode;
import com.jmex.physics.material.Material;

public class TestFlyer implements TargetAble{
   private static final float dampeningrotation = 0.89f;
   private static final float dampeningmove = 0.99f;
   private static final int forwardforce = 500;
   private static final int strafeforce = 200;
   private static final float rollchange = 0.1f;
   private static final float udforce = 1f;
   private static final float rlforce = 1f;
   
   private SolarSystem system;
   private CameraController cam;
   private DynamicPhysicsNode flyobject;
   private Quaternion NullToShouldBe = new Quaternion();
   private int hp = 100;
   private int shield = 100;
   
   
   
   public TestFlyer(SolarSystem mysystem){
      this.system = mysystem;
      this.cam = CameraController.Get();
      this.flyobject = this.system.getPhysicspace().createDynamicNode();

      Box mycoldata = new Box("TestFly",new Vector3f(0,0,0), 1,1,1);
      this.flyobject.attachChild(mycoldata);
      this.flyobject.setMaterial(Material.CONCRETE);
      this.flyobject.generatePhysicsGeometry(true);
      this.system.getSystemnode().attachChild(this.flyobject);
      
      NullToShouldBe.normalize();
      
      MassiveSpaceEngine.AddShadowedObject(flyobject);
   }
   
   public void Update(float interpolate){
      ApplyForce(interpolate);
      
      System.out.println(this.flyobject.getAngularVelocity(null));
      
      this.flyobject.setLinearVelocity(this.flyobject.getLinearVelocity(null).mult(dampeningmove));
      this.flyobject.setAngularVelocity(this.flyobject.getAngularVelocity(null).mult(dampeningrotation));
      
      this.cam.setLocalRotation(this.flyobject.getLocalRotation());
      this.cam.setLocalTranslation(this.flyobject.getLocalTranslation().add(this.flyobject.getLocalRotation().GetForward().mult(-10)));
   }

   private void ApplyForce(float interpolate) {
      KeyInput keysystem = MassiveSpaceEngine.Get().getKeySystem();
      if(keysystem.isKeyDown(KeyInput.KEY_W)){
         Vector3f forwardvec =this.flyobject.getWorldRotation().GetForward();
         this.flyobject.addForce(forwardvec.mult((forwardforce*interpolate)));
      }
      if(keysystem.isKeyDown(KeyInput.KEY_S)){
         Vector3f forwardvec = this.flyobject.getWorldRotation().GetForward();
         this.flyobject.addForce(forwardvec.mult(-(forwardforce*interpolate)));
      }
      if(keysystem.isKeyDown(KeyInput.KEY_A)){
         Vector3f forwardvec = this.flyobject.getWorldRotation().GetRight();
         this.flyobject.addForce(forwardvec.mult((strafeforce*interpolate)));
      }
      if(keysystem.isKeyDown(KeyInput.KEY_D)){
         Vector3f forwardvec = this.flyobject.getWorldRotation().GetRight();
         this.flyobject.addForce(forwardvec.mult(-(strafeforce*interpolate)));
      }
      if(keysystem.isKeyDown(KeyInput.KEY_SPACE)){
         Vector3f forwardvec = this.flyobject.getWorldRotation().GetUp();
         this.flyobject.addForce(forwardvec.mult(strafeforce*interpolate));
      }
      if(keysystem.isKeyDown(KeyInput.KEY_LSHIFT)){
         Vector3f forwardvec = this.flyobject.getWorldRotation().GetUp();
         this.flyobject.addForce(forwardvec.mult(-strafeforce*interpolate));
      }
      
      if(keysystem.isKeyDown(KeyInput.KEY_Q)){
         Vector3f forwardvec = this.flyobject.getLocalRotation().GetUp().mult(rollchange);
         this.flyobject.addForce(forwardvec,new Vector3f(-10,0,0));
      }
      if(keysystem.isKeyDown(KeyInput.KEY_E)){
         Vector3f forwardvec = this.flyobject.getLocalRotation().GetUp().mult(rollchange);
         this.flyobject.addForce(forwardvec,new Vector3f(10,0,0));
      }
      
      float deltay = MouseManager.Get().RelativeGetY()*udforce;
      float deltax = MouseManager.Get().RelativeGetX()*rlforce;
      
      if(!MouseManager.Get().isOverGui()){
         if(MouseManager.Get().MousePressed(MouseKey.Left)){
            Vector3f forwardvec = this.flyobject.getLocalRotation().GetUp().mult(deltay);
            this.flyobject.addForce(forwardvec,new Vector3f(0,0,10));   
            
            Vector3f forwardvec2 = this.flyobject.getLocalRotation().GetForward().mult(deltax);
            this.flyobject.addForce(forwardvec2,new Vector3f(10,0,0));   
         }
      }
   }

   @Override
   public boolean Destroyable() {
      return true;
   }

   @Override
   public String GetDescription() {
      return "A Testbox that can fly";
   }

   @Override
   public int GetHp() {
      return this.hp;
   }

   @Override
   public int GetShield() {
      return this.shield;
   }

   @Override
   public Signature GetSiganture() {
      return null;
   }
}

Empire,



  I just merged up the fixes to addForce() into trunk from the jbullet-integration branch.  That should take care of your addForce() issues.  (Has to do with the odd way that JBullet does its time-stepping . . . if your fame render is shorter than the minimum 'step', it'll interpolation motion, but not actual physics calculations.  So . . . force * 0 (since your frame was shorter than 1/60 second) =0.  Only when framerate drops does the calc actually work right.  That's fixed with this merge.)



  As far as your velocities go . . . you haven't rendered a step in your physics simulation, so there's no way to know what your velocities are.  Your 'ApplyForce()' method calls the right 'addForce()' methods, but there's two problems you'll have to deal with.


  1. As I mentioned, the physics sim hasn't calculated your velocities yet, so 'mult()'-ing a 0 velocity will always get you 0.  That will change a bit with the addForce() fix, but your damping will still be a bit wierd, I think.
  2. As you apply your damping, there's no way to know if the velocity you're damping is a result of your applied forces, or some other forces, i.e. Gravity, collision, etc.  If you you're okay with that, no biggie.



      In any case, go ahead and pull down those changes and let me know what happens next.  That'll take care of some of your problems.



      -Falken

Well it's in space and there is currently nothing else that can affect it, except itself.



Will test it with the latest update later, when I'm finished with work :slight_smile:

Well finally my weekend starts :slight_smile:



Now I updated everything, but still get the same error.



I'm unable to affect my dynamicphysicsnode whatever I do, except setting a DirectionalForce for the PhysicsSpace :frowning:

I tested if I'm able to find any mistake, but I'm not, it seems that everything works perfectly at least I have understandable and possible values for force to add ect, down to the function calls in the jbulletjar.



The thing I mostly wonder about, why does the Teststuff work, but my stuff not?



If you have any further Ideas, I would be really gratefull.

Nice work :)  good call to utilize Bullet i jME, Bullet is tested, widely used, and hold many qualified developers.



I have a comment about the joint/spring stuff that you mention, Falken.  If I understand correctly, the JME interface allows you to specify that joint forces should be like springs, to create a soft constraint effect. The problem with this is, that joint in a constraint based approach like the one in Bullet (and all other engines I know of, not sure about ODE though),  the forces that act inside a joint is modeled as a constraint force, which does not behave like a spring at all. It's possible to create a softening effect by limiting the magnitude of the constraint forces, so that it cannot pull the joint together too fast. Maybe that is the way to solve the issue?






Heya Empire,



  Took a closer look at that code you posted.  I don't know if you realize it, but when you call 'addForce' for all your keypress methods, you're multiplying your force times your interpolation value.  (I'm assuming 1/framerate)  While this SEEMS good, on the surface, you have to remember that 'force' isn't scaled with time, 'impulse' is.  (force*time=impulse)



  So, in your keypress methods, assuming you have a game running at 100 fps, you're dividing your force by 100 before applying it.  I'm pretty sure that's not what you want.  :)  Try holding down your keys for a minute and a half and I'll bet you see a TEEEEEEEEEEENY bit o' movement.  :slight_smile:



  That's suggestion #2.  Ping me again if that still doesn't work, 'cause if it really is a problem with the engine, I definitely want to get to the bottom of it.



-Falken

Hm nope I removed the interpolation stuff, but it should make no difference, since I'm running on a fixed Logicrate O.o



I really wonder what the problem is then, I attached a full source of what i have untill now, intresting classes are probably Testflyer and Solarsystem and maybee MassiveSpaceEngine:



I hope this helps you finding the error and me fixing it :slight_smile:



(Still I wonder that it works with the other implementations)





PLEASE DON'T DOWNLOAD IF YOU ARE NOT INVOLVED IN THIS, SINCE IT CAN ONLY LOADED 10 TIMES

http://rapidshare.com/files/298503010/Srcv1.rar.html