Rigid Body Dynamics Library

December 7, 2011

Hi there…

some time ago, I posted a video about my C++ implementation of the Articulated Body Algorithm (ABA), one of the best available algorithms available to perform forward dynamics computations on kinematic tree structures (if this sounds weird, replace “forward dynamics computations” by “physics simulations” and “kinematic tree structures” by “human-like figures” and you might be able to get a clue what you can do with it).

I mostly use it for my scientific work, which is funded by the Heidelberg Graduate School of Mathematical  and Computational Methods for the Sciences. I spent quite some time in programming it and making sure it does what it should (91 tests!).

Some highlights:

So far I am very happy with it and thought that maybe other can benefit from it as well.

Therefore I decided to publish it under an open-source license, namely the very permissive zlib license (which is also used by Bullet), which should allow pretty much anyone to do what he/she/it wants with it. However comments, suggestions or acknowledgements are still very welcome.

You can grab it at:

https://bitbucket.org/MartinFelis/rigidbodydynamicslibrary

It does feel a little weird to let it out into the wild, but I hope it is of use for anyone.

Martin

OpenGL is dead! Long live OpenGL! (a.k.a. IFTPOP 0.0.2a)

November 20, 2011

I think finally tracked the error that made the game crash on some computers. The culprit is OpenGL, more specifically OpenGL 1.X. Since the introduction of OpenGL 2.0 in 2004 there have been a few changes in the way how to do graphics (“it’s called shader baby!”). As my current reference of OpenGL (the OpenGL Super Bible, 5th ed.) tries to break free from the old legacy code (“fixed function pipeline”) I ended up being dependent on this new stuff.

Sorry about that. But if it does not run, you probably should get a new computer anyways.

At least some good news: errors are now nicely reported with a message box. Should your graphics card be incompatible, you will beinformed properly.

Get it from here: iftpop_0.0.2a

A new version with better graphics (OpenGL 2.X!) is coming along as I now finally fixed this error.

Tags

Custom Shaders and Material in Horde3D

November 15, 2011

To simplify scene management and visual effects I looked at various open-source graphic engines that I might use. I briefly looked at the usual suspects such as Ogre3D and Irrlicht until I found Horde3D, which convinced me by its simple looking API and the compiled library was much smaller than of the others. It also seemed to feature various capabilities that might be interesting (scene graph, shadow mapping) or nice to have things (picking, blur, hdr, etc.).

However being an old-school OpenGL programmer, that mostly draws simple geometries such as cubes, spheres, and similar, it is not quite the way I am used to do stuff. Furthermore, the shaders in the examples seemed much more advanced than I need for now, so I am currently trying to make things more basic. Eventually I want to use the scene graph to do some procedural animation and that I am going to do with these simple geometries. Using more sophisticated models created with blender should not be too hard once I got it running.

So far I incorporated Horde3D to my code and using assets from the example to get some experience with Horde3D and implemented a simple shader. As I had the OpenGL Superbible laying around I thought it would be nice to implement the good old Ambient-Diffuse-Specular lighting model (so far only on a per-vertex basis).

Here are some screenshots of the different steps I took:

Now I can easily specify the material in the XML-files that Horde3D is using. Also, I learned a great deal about Horde3D.

Hopefully I’ll soon be able to draw simple procedurally generated geometries and can then start to look at the animations.

Tags

Have a better day!

November 9, 2011

(click for full image)

 

Yesterday I drew something. I tried to capture a very specific mood. It may or may not be iftpop related.

For the game itself there is nothing much to see, as I am currently switching the graphics framework (actually I am switching to *a* framework) and therefore everything is black – yay!

Have a better day!

Martin

Tags

Wall Jumps!

October 31, 2011

Did some work on the controller, which is getting feature complete more or less. It now allows for wall-runs and wall-jumping. Have a look at the new version and try to climb the two pillows.

Also, I added quite a bit of doxygen documentation to btKinematicCharacterController. For the interested I created a repository over at github (https://github.com/martinfelis/bulletphysics2) that contains the changes I made.

There are also improvements to the camera movement. There is no more jittering (thanks to the insights I gained about btKinematicCharacterController) and also the horizontal movement is no more constrained = much more fun!

Oh, and here is the new (windows) version: iftpop_0.0.2. Go Try It! NOW!

Additionally, I spilled some wine over my desktop keyboard.

IFTPOP 0.0.1 for Windows

October 17, 2011

All right! Windows version of the current code ready!

Grab it from here: iftpop-0.0.1

So far I am working on the controls for both camera and player movement. With the camera I am quite happy, but the player will get some more action features such as wall-jump and duck-slide, etc.

The camera starts to jitter at some point, but I do not yet know why.

Some informations about the game: it will feature some elements from racing games. And platformers. And nightmares.

Cheers,
Martin

Tags

New game: IFTPOP! first screenshot

October 14, 2011

Just a small screenshot of the current state of my next game, called “IFTPOP!” (what it actually means might be revealed at some point). The code so far is based upon my previous asteroids game but with a lot of new development. Biggest change so far: integration of bullet physics.

So long,
Martin

Tags

Scala + LWJGL + AWT = Resizable OpenGL Window

September 28, 2011

Following up on my previous post, I played around a bit more with Scala and LWJGL. What bothered me is that the standard examples for LWJGL and Scala had no resizable windows. But this is no more the case! It took me a bit to figure out how to translate various bloated Java examples to Scala but I am happy with the result.

Here is the code (btw.: does someone know how to make WP-Syntax a bit nicer looking?):

/**
 * Example program to get a resizable window using LWJGL + AWT in Scala.
 *
 * This code is public domain. Feel free to use it for anything you like.
 */
package org.fysx.lwjgltools
 
import java.awt._
import java.awt.event.{ComponentEvent, ComponentAdapter, WindowAdapter, WindowEvent}
import java.util.concurrent.atomic.{AtomicReference, AtomicBoolean}
 
import org.lwjgl._
import opengl.{Display,GL11,DisplayMode}
import GL11._
import input._
import math._
import org.lwjgl.opengl.AWTGLCanvas
 
class LWJGLFrame(text: String) extends Frame(text) {
  // tells us whether the screen was resized
  var resized = new AtomicBoolean()
  // the canvas on which the OpenGL context will be drawn
  var canvas = new Canvas()
  // this will store the new size after a resize
  var newCanvasSize = new AtomicReference[Dimension]
  // will be true if we received a window close request
  var closeRequested = false
  // used when resizing
  var newDim = new Dimension()
  // used for some animation
  var c = 0.0f
  var delta_c = 0.01f
 
  // added constructor in case we did not specify a String to LWJGLFrame()
  def this() {
    this("")
  }
 
  // add listener to the resize event
  canvas.addComponentListener (new ComponentAdapter() {
    override def componentResized(e: ComponentEvent) = {
//      println ("new size")
      newCanvasSize.set(canvas.getSize())
    }
  })
 
  // add the canvas our LWJGLFrame
  add(canvas, BorderLayout.CENTER)
 
  // add listener to the window close event
  addWindowListener(new WindowAdapter() {
    override def windowClosing (e: WindowEvent) = {
//      println ("close requested")
      closeRequested = true
    }
  })
 
  // adjust OpenGL context for change of the window size
  def resize() {
    newDim = newCanvasSize.getAndSet(null)
 
    if ( newDim != null ) {
//      println ("updating viewport")
      GL11.glViewport(0, 0, newDim.width, newDim.height)
    }
  }
 
  // perform the actual drawing
  def render() {
    c = c + delta_c
    if (c > 1.0f || c < 0.0f) delta_c = delta_c * -1.f
 
    GL11.glClearColor (0, 0, 0, 0)
    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT)
 
    glColor3f (1.0f, 1.0f, 1.0f)
    glBegin(GL_TRIANGLES)
    glColor3f (0.25f, 1-c, 0.25f)
    glVertex3f (-0.5f, -0.75f, 0.0f)
    glColor3f (0.5f, 0.25f, 1.0f-c)
    glVertex3f (0.5f, -0.75f, 0.0f)
    glColor3f (c, 0.5f, 0.25f)
    glVertex3f (0.f, 0.75f, 0.0f)
    glEnd
  }
 
  // handle keyboard and other events
  def logic() {
    import Keyboard._
 
    if (isKeyDown(KEY_I)) println ("Key I was pressed!")
  }
 
  // starts the OpenGL loop
  def run() {
//    println ("executing run()")
    try {
      // setup of the Display (connect it to the canvas)
      Display.setParent(canvas)
      try {
        Display.create()
      } catch {
        case e: LWJGLException => {
          e.printStackTrace()
          println (e.getMessage())
        }
      }
 
      Display.setVSyncEnabled(true)
 
      // the actual main loop
      while (!Display.isCloseRequested() && !closeRequested) {
        resize()
        Display.update()
 
        logic()
 
        render()
 
        Display.sync(60)
      }
 
      // we're done so we have to destroy the Display
      Display.destroy()
    }
  }
}
 
object Main {
  // actual entry point of the program
  def main(args: Array[String]) {
    var lwjglframe = new LWJGLFrame ("Scala + LWJGL + AWT = resizable window")
 
    lwjglframe.setMinimumSize(new Dimension(320, 240))
    lwjglframe.setSize(new Dimension(640, 480))
    lwjglframe.setVisible(true)
 
    lwjglframe.run()
 
    lwjglframe.dispose()
  }
}

Tags

Scala + LWJGL = Running Program

September 22, 2011

scala + lwjglI thought I would try to get the Lightweight Java Game Library (LWJGL) running in Scala as both are really hip nowadays. Turns out that there is not much available on teh internets that works. Most of them use the “Simple Build Tool” (sbt) which I did not find simple at all. Also they have a new version 0.10.x which is incompatible to the Scala+LWJGL examples which use sbt version 0.7.x. Yay!

Anyhow, I used the Scala code from http://lwjgl.org/forum/index.php?topic=3416.0 and finally managed to get it run without any “simple” tools or other dependencies. Here is how:

  1. Download the current LWJGL release (as of writing: 2.7.1). This should give you a zip file with a few jars, dlls and so files.
  2. Download and install Scala from http://www.scala-lang.org/ (as of writing: 2.9.1)
  3. Create the folders “lwjglproject/lib” and “lwjglproject/src”
  4. Extract all .jars to “lwjglproject/lib”. When using Windows do so with the dlls, on Linux put the .so files there and Mac users probably don’t have to do anything (that’s what I’m always being told)
  5. Create a source file “lwjglproject/src/lwjgl.scala” with contents from the example (also available further down)
  6. Compile the code with
    scalac -classpath ./lib/lwjgl.jar src/lwjgl.scala

    this should  give you some .class files

  7. Run the example by executing
    scala -classpath lib/lwjgl.jar -Djava.library.path=./lib Main
  8. Enjoy

Oh, and if you want to run the program directly with java to have to specify the path to scala-library.jar and add the (current) “lwjglproject” path to the classpath:

java -classpath .:lib/lwjgl.jar:/lib/scala-library.jar -Djava.library.path=./lib Main

Here is the code for the example:

import org.lwjgl._
import opengl.{Display,GL11,DisplayMode}
import GL11._
import input._
import math._
 
object Main{
	val GAME_TITLE = "My Game"
	val FRAMERATE = 60
	val width = 640
	val height = 480
 
	val player = new Player(0,0,0);
 
	var finished = false
	var angle = 0.0f
	var rotation = 0.0f
 
	def main(args:Array[String]){
		var fullscreen = false
		for(arg <- args){
			arg match{
				case "-fullscreen" =>
					fullscreen = true
			}
		}
 
		init(fullscreen)
		run
	}
 
	def init(fullscreen:Boolean){
 
		println("init Display")
		Display.setTitle(GAME_TITLE)
		Display.setFullscreen(fullscreen)
		Display.setVSyncEnabled(true)
		Display.setDisplayMode(new DisplayMode(width,height))
		Display.create
 
		println("init gl")
		glEnable(GL_DEPTH_TEST);
		glEnable(GL_LIGHTING)
		glEnable(GL_LIGHT0)
		adjustcam
	}
 
	def adjustcam(){
		val v = Display.getDisplayMode.getWidth.toFloat/Display.getDisplayMode.getHeight.toFloat
		printf("v:%f",v)
		glMatrixMode(GL_PROJECTION)
		glLoadIdentity
		glFrustum(-v,v,-1,1,1,100)
		glMatrixMode(GL_MODELVIEW)
	}
 
	def cleanup(){
		Display.destroy
	}
 
	def run(){
		while(!finished){
			Display.update
 
			logic
			render
 
			Display.sync(FRAMERATE)
		}
	}
 
	def logic(){
	    // in scala we can locally import all methods from Keyboard.
	    import Keyboard._
 
		if(isKeyDown(KEY_ESCAPE))
			finished = true
		if(Display.isCloseRequested)
			finished = true
 
		// rx and rx store our keyboard input as direction  
		var ry = 0
		var rx = 0
 
		// keys are IKJL for up down left right
 
		if(isKeyDown(KEY_I))
			ry += 1
		if(isKeyDown(KEY_K))
			ry -= 1
		if(isKeyDown(KEY_J))
			rx -= 1
		if(isKeyDown(KEY_L))
			rx += 1
 
		// this makes the direction relative to the camera position
		// it is a simple rotation matrix you may know from linear algebra
		val ax = rx*cos(-rotation.toRadians)-ry*sin(-rotation.toRadians)
		val ay = rx*sin(-rotation.toRadians)+ry*cos(-rotation.toRadians)
 
		player.x += 0.1f*ax.toFloat
		player.y += 0.1f*ay.toFloat
 
		// this rotates our camera around the center
		angle += 2.0f % 360
		rotation += 0.2f
	}
 
	def renderGrid(size : Int){
	    // this creates the nice looking background.
		glDisable(GL_LIGHTING)
		glBegin(GL_LINES)
		for(i <- -size to size){
			glVertex2i(i,-size)
			glVertex2i(i, size)
			glVertex2i(-size,i)
			glVertex2i( size,i)
		}
		glEnd
		glEnable(GL_LIGHTING)
	}
 
	def render(){
		glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glLoadIdentity
 
		glTranslatef(0,0,-20)
		glRotatef(-70,1,0,0)
		glRotatef(rotation,0,0,1)
 
		glPushMatrix
		player.applyPos
		//rotate the player just for fun
		glRotatef(angle, 0, 0, 1.0f)
		player.draw
		glPopMatrix
 
		//without background, motion is not visible
		// a green grid is nice and retro
		glColor3f(0,1,0)
		renderGrid(10000)
	}
}
 
class Player(nx:Float,ny:Float,nz:Float){
	var x:Float = nx
	var y:Float = ny
	var z:Float = nz
 
	def applyPos {
	    glTranslatef(x,y,z)
	}
 
	def draw = {
		glColor3f(1, 0, 0)
		glBegin(GL_TRIANGLE_FAN)
		glNormal3d( 0, 0, 1);	glVertex3d(0,0,0.5)
		glNormal3d(-1,-1, 1);	glVertex2d(-0.5, -0.5)
		glNormal3d( 1,-1, 1);	glVertex2d(0.5, -0.5)
		glNormal3d( 1, 1, 1);	glVertex2d(0.5, 0.5)
		glNormal3d(-1, 1, 1);	glVertex2d(-0.5, 0.5)
		glNormal3d(-1,-1, 1);	glVertex2d(-0.5, -0.5)
		glEnd
	}
}

Tags

Asteroids finished!

May 8, 2011

Please note the “1.0.0” at the top bar or at the bottom-left of the screen. Or just help yourself with one of these:

You may now call me a game developer.

Something more elaborate will follow, but for now I just have to enjoy the moment!

Tags