Rotating a vector by a quaternion in GLSL

Posted in How To, Programming with tags , , , , on 2013/02/11 by Adam Griffiths

I’ve found numerous code samples which produce erroneous results in my shaders.

The functions I’ve found to work are the following:

 vec4 multQuat(vec4 q1, vec4 q2) { return vec4( q1.w * q2.x + q1.x * q2.w + q1.z * q2.y - q1.y * q2.z, q1.w * q2.y + q1.y * q2.w + q1.x * q2.z - q1.z * q2.x, q1.w * q2.z + q1.z * q2.w + q1.y * q2.x - q1.x * q2.y, q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z ); }

 

vec3 rotate_vector( vec4 quat, vec3 vec ) { vec4 qv = multQuat( quat, vec4(vec, 0.0) ); return multQuat( qv, vec4(-quat.x, -quat.y, -quat.z, quat.w) ).xyz; } 

And this version which is optimised:

 vec3 rotate_vector( vec4 quat, vec3 vec ) { return vec + 2.0 * cross( cross( vec, quat.xyz ) + quat.w * vec, quat.xyz ); } 

Using gl_VertexID without any VBOs.

Posted in How To, Programming with tags , , , on 2013/02/03 by Adam Griffiths

Normally, gl_VertexID is the index of the currently rendered vertex element.

When you provide indices (GL_ELEMENT_ARRAY_BUFFER), gl_VertexID should match the value provided. Ie, the gl_VertexID value can repeat if you render the same element multiple times.

I say “should”, because this is NOT correct when you haven’t provided any VBO data.

This means, that if you are rendering using nothing but a shader and a GL_ELEMENT_ARRAY_BUFFER, the gl_VertexID will NOT match the indices you provide, and will instead be a sequence from 0 -> N.

The solution is to use a single VBO and use glDrawArrays.

Personally, I consider this a bug.

Adobe Air hanging when using SDK but not when packaged

Posted in How To with tags , , , , , on 2013/01/30 by Adam Griffiths

I just had an issue during the development of an Adobe AIR Application.
When using Flash Pro CS 6, the application hang in certain situations for 5 odd seconds.

I found a few peculiar quirks:

• Packaged builds didn’t have the problem.
• Moving the project to a different directory fixed the problem.
• Clean checkouts of the source didn’t have the problem
• Re-creating the project in Flash Pro CS 6 didn’t fix the problem.

The console was printing the following messages
 Breakpoint not set; No executable code at line ### 

It turns out the problem was old breakpoints that don’t exist anymore.
There’s not trivial way to remove all the breakpoints (the button was greyed out!).
The easiest way I found (on OS-X) was to do the following:

 vi ~/Library/Application\ Support/Adobe/Flash\ CS6/en_US/Configuration/Debugger/AsBreakpoints.xml 

Remove all the breakpoint entries in the XML.
The file should look similar to this:

 <?xml version="1.0"?> <flash_breakpoints version="1.0"> </flash_breakpoints> 

This resolved the issue.

Compiling Python on Ubuntu / Linux

Posted in Twisted Pair with tags , , , , on 2012/09/25 by Adam Griffiths

I’ve been having problems installing Python on my Ubuntu machine because of errors with setup tools.

During installation you get the following error:

Installing distribute into /home/ting/.pythonbrew/pythons/Python-2.7.3
ERROR: Failed to install setuptools. See /home/ting/.pythonbrew/build.log to see why.
Skip installation of setuptools.


And if you try and use pip / easy_install, you get this:

ImportError: No module named setuptools


It turns out the answer is simple, we’re missing some libraries required to compile it.

sudo apt-get build-dep python2.7


BAM! Pythonbrew works!

Getting Cocos 1.x / Kobold2D to work with the latest CocosBuilder

Posted in Development, How To, Programming, Rant with tags , , , , , on 2012/03/30 by Adam Griffiths

CocosBuilder is a brilliant tool that helps you rapidly develop Cocos2D applications.

Some of us are stuck with Cocos 1.x for the time being. So let’s figure out how to get things going.

Install GCC with XCode 4.3

Posted in How To with tags , , , , on 2012/03/21 by Adam Griffiths

XCode 4.3 removed GCC from the default installation. To get it back simply do the following:

1. Run XCode
2. Select XCode -> Preferences -> Downloads -> Command Line Tools -> Install

Voila! GCC is now installed and libraries such as PIL will once again install.

Installing Kivy on OS-X from PIP and Homebrew

Posted in How To, Programming with tags , , , , , on 2012/03/19 by Adam Griffiths

Begin by following this guide to get your python environment setup.

If you aren’t using virtualenv, then feel free to ignore those commands (mkvirtalenv, cdvirtualenv).

Remember to run ‘brew’ commands as the current user and not root.

Install SDL

brew install sdl sdl_image sdl_mixer sdl_ttf smpeg portmidi


brew install mercurial


Create a virtual environment to work in

mkvirtualenv kivy
cdvirtualenv


Install our Kivy dependencies and then finally, Kivy itself.

pip install cython
pip install pil
pip install hg+http://bitbucket.org/pygame/pygame</pre>
pip install kivy


If you don’t install PIL or PyGame, you will get errors such as this

(kivy-test)Vibur:kivy-test adamgriffiths$python src/main.py [INFO ] Kivy v1.1.1 [INFO ] [Logger ] Record log in /Users/adamgriffiths/.kivy/logs/kivy_12-03-19_4.txt [INFO ] [Factory ] 102 symbols loaded [WARNING] [Image ] Unable to use <pygame> as loader! [WARNING] [Image ] Unable to use <pil> as loader! [WARNING] [Text ] Unable to use <pygame> as textprovider [WARNING] [Text ] Associated module are missing [WARNING] [Text ] Unable to use <pil> as textprovider [WARNING] [Text ] Associated module are missing [CRITICAL] [Text ] Unable to find any valuable Text provider at all! Traceback (most recent call last): File "src/main.py", line 2, in <module> from kivy.uix.button import Button File "/Users/adamgriffiths/Workspace/VirtualEnvs/kivy-test/lib/python2.7/site-packages/kivy/uix/button.py", line 38, in <module> from kivy.uix.label import Label File "/Users/adamgriffiths/Workspace/VirtualEnvs/kivy-test/lib/python2.7/site-packages/kivy/uix/label.py", line 94, in <module> from kivy.core.text import Label as CoreLabel File "/Users/adamgriffiths/Workspace/VirtualEnvs/kivy-test/lib/python2.7/site-packages/kivy/core/text/__init__.py", line 520, in <module> Label.register('DroidSans', AttributeError: 'NoneType' object has no attribute 'register'  Installing Virtualenv and Pythonbrew on OS-X Posted in How To, Programming with tags , , , on 2012/03/19 by Adam Griffiths This post will help you get Pythonbrew and Virtualenv installed on OS-X. Two important libraries for Python development. • Pythonbrew lets you install multiple python installations without affecting your system’s Python install. • Virtualenv lets you set up isolated python installations and modules for each project. Begin by installing Pythonbrew # install pythonbrew locally # do NOT install to your system python directory curl -kL http://xrl.us/pythonbrewinstall | bash  Install your desired Python versions # get a list of available python versions python list -k # install desired python # force the install as python fails some tests at the moment # https://twistedpairdevelopment.wordpress.com/2012/01/16/installing-python-with-pythonbrew-on-mac-os-x pythonbrew install <VERSION> pythonbrew use # should print out python --version # virtualenvwrapper must be installed for each python version pip install virtualenvwrapper  You can install virtualenv and virtualenvwrapper into the system Python, or into your newly installed python. # install into system python # do this if you plan to use the system python as default sudo pip install virtualenv sudo pip install virtualenvwrapper  You can install virtualenv and virtualenvwrapper into the system Python, or into your newly installed python. # install into pythonbrew installed python # do this if you want to over-ride the default python installation pythonbrew switch <VERSION> pip install virtualenv pip install virtualenvwrapper  Add support for Pythonbrew to bash by adding the following to the end of your ~/.bashrc #------------------------------------------------------------- # Python definitions #------------------------------------------------------------- # Pythonbrew # add pythonbrew support if [[ -s$HOME/.pythonbrew/etc/bashrc ]]; then
source $HOME/.pythonbrew/etc/bashrc fi  Add virtualenvwrapper support to ~/.bashrc  #------------------------------------------------------------- # Python definitions #------------------------------------------------------------- # Virtualenvwrapper # virtualenv wrapper support export WORKON_HOME=~/Workspace/VirtualEnvs if [[ -s /usr/local/bin/virtualenvwrapper.sh ]]; then source /usr/local/bin/virtualenvwrapper.sh fi # PIP # tell pip to only install inside virtualenvs export PIP_REQUIRE_VIRTUALENV=true # make pip use the virtualenv dir export PIP_VIRTUALENV_BASE=$WORKON_HOME

# use eval to avoid the error "Could not find an activated virtualenv (required)."
eval pip completion --bash



When creating Virtualenv environments, virtualenv will use the currently set Python install.

If you wish to use a Python install other than the current system install, run the following command before running mkvirtualenv.


pythonbrew use <VERSION>



Note: I’ve found that virtualenvwrapper has stopped obeying this. To force virtualenvwrapper to install a specific version, do the following.

pythonbrew use <VERSION>
MY_PYTHON="$(command which python)" mkvirtualenv -p$MY_PYTHON <NAME>


Some basic Virtualenvwrapper commands:

• mkvirtualenv PROJECTNAME – create a new virtualenv project.
• workon PROJECTNAME – enter the virtualenv for the project.
• deactivate – stop working on the current virtualenv project.
• cdvirtualenv – change to the directory of the current virtualenv project.

If you need to add environment variables to your project, edit the ‘bin/postactivate’ file inside the virtualenv directory. This file is executed when the ‘workon’ command is run and can be used to add more paths to \$PYTHONHOME and other useful commands.

Python weak references to Methods and Functions

Posted in Development, How To, Programming with tags , , on 2012/03/01 by Adam Griffiths

The ‘weakref’ module in Python cannot store pointers to methods (there are exceptions but basically you can’t).

The following is a module I’ve written to bypass this. It is essentially code from the following sites, but improved by myself for storing them in containers like set([]).

References:
[1] [2]

Installing Pyglet in Mac OS X

Posted in Development, Platforms, Programming with tags , , , , , on 2012/02/21 by Adam Griffiths

Pyglet is a common requirement for many Python applications, a major one being Cocos2D.

But it doesn’t work out of the box. Running a Pyglet application will result in the following error:

OSError: dlopen(/System/Library/Frameworks/QuickTime.framework/QuickTime, 6): no suitable image found.  Did find:

/System/Library/Frameworks/QuickTime.framework/QuickTime: mach-o, but wrong architecture

/System/Library/Frameworks/QuickTime.framework/QuickTime: mach-o, but wrong architecture


The following are the steps to take to get Pyglet and PyObjc installed on OS-X (tested with 10.7 Lion).

Pyglet 1.1 uses the Carbon framework, but this is not compatible with 64-bit Python installs. The Pyglet 1.2 branch has been modified to use Quartz, but no releases of this branch have seen the light of day (sigh). We must instead install Pyglet from the Mercurial repository.

The Quartz bindings require the use of PyObjc but the latest versions do not work with Pip. The patches to PyObjc’s setup.py that I’ve seen on the internet do not work for me. The following is the only method I’ve had work.

Remove any existing Pyglet install

pip uninstall pyglet

Install Pyglet from the repository

pip install hg+https://pyglet.googlecode.com/hg/

Edit: The following is no longer needed

We need to install PyObjc for the new Pyglet Quartz API. But PyObjc is horribly broken and the latest version does not install with Pip or easy_install.

We must instead install an older version.

pip install pyobjc==2.2

You should now have a working Pyglet installation.

Making .bashrc modular (and awesome)

Posted in How To, Platforms with tags , , on 2012/01/26 by Adam Griffiths

.bashrc files quickly get complex.

Putting them into revision control is handy for persistance, but not always the best for sharing when not everyone has the same environment.

So lets fix that! Continue reading

Posted in How To, Platforms with tags , , , , , on 2012/01/17 by Adam Griffiths

I’ve created a page with a concise list of instructions for setting up and managing the DLink 323.

I’m considering moving some of the less “blog” style posts into pages to keep them in a single place.

Pyglet mouse events and rendering

Posted in Development, How To, Programming with tags , , , , on 2011/06/28 by Adam Griffiths

The Problem

I added mouse event handlers to my Pyglet application recently. I found when I moved the mouse over the window, my rendering started to create “ghost” images.

I finally found the solution hidden in the docs.

The pyglet application event loop dispatches window events (such as for mouse and keyboard input) as they occur and dispatches the on_draw event to each window after every iteration through the loop.

So every mouse move (or any other event) triggers Pyglet to call “on_draw”.

But because I’m controlling my own render loop at 60Hz, I didn’t see a need to hook into this event. So I assume Pyglet is attempting to render the scene itself, and it’s failing miserably.

This is really bad design! What if I have lots of events that are seperate? Looks like Pyglet is going to hammer the “on_draw” event.

The Solution?

Well the basic solution is to ensure you’ve hooked into the “on_draw” event and just connect it to your render call. Don’t connect it to your game update logic or you will end up updating everything.

But…

This means your frame rate will vary depending on user input, and may even end up running balls out. Which could turn a simple game into a system hog. My basic application goes from 1% (of 2 cores on a dual core system), to 20% with the mouse moving.

It also means that you need to decouple the rendering from the system update, as each event you have scheduled will trigger an “on_draw” event. If you don’t decouple them, you will render each frame twice!

The Proper Solution?

We need to over-ride the “EventLoop.idle” method as mentioned in the docs.

The code without “on_draw” looks like this:

def idle( self ):
"""An alternate idle loop than Pyglet's default.

By default, pyglet calls on_draw after EVERY batch of events
which without hooking into, causes ghosting
and if we do hook into it, it means we render after every event
http://www.pyglet.org/doc/programming_guide/the_application_event_loop.html
"""
pyglet.clock.tick( poll = True )
# don't call on_draw
return pyglet.clock.get_sleep_time( sleep_idle = True )

def patch_idle_loop():
"""Replaces the default Pyglet idle look with the :py:func:idle function in this module.
"""
# check that the event loop has been over-ridden
if pyglet.app.EventLoop.idle != idle:
# over-ride the default event loop
pyglet.app.EventLoop.idle = idle


The “on_draw” function also calls pyglet.window.flip() for us, so now we need to do that after our rendering. So add the following (obviously you need to change the window variable depending on what you’ve called it):

# switch out the default idle function for ours
patch_idle_loop()

def render( self ):
# do render here
# flip the buffers
self.window.flip()


And we’re done! No more superfluous “on_draw” events and my simple application no longer spikes the CPU usage when the mouse is moved!

Example of Minecraft style polygonisation

Posted in Development, Programming with tags , on 2011/06/17 by Adam Griffiths

Good walkthrough of rendering a voxel volume from start to finish in a Minecraft style.

It has the following problems however:

• Single volume, no hierarchy.
• Lack of hierarchy makes polygonisation harder, it must be done in one sweep.
• Lack of hierarchy makes modification harder.
• It performs 2 sweeps of the volume, one to calculate number of primitives, another to create them.
• The C functions don’t compile in MSVC2008.

But it’s a good source of information on lighting and shader implementations.

RLE? That’s so yesterday!

Posted in Development, How To, Programming with tags , , , on 2011/06/11 by Adam Griffiths

Before writing my RLE implementation, a friend sent me a link to the blist package for Python.

I didn’t see anything amazing on the front page. Makes a 5M size list. Sure, whatever.

What the front page fails to say is that creating that 5M size blist is insanely fast. Because it doesn’t blindly allocate memory like a normal Python list would.

The “blist” list type is faster to add / remove than a Python list, and it supports copy-on-write semantics.

So I’m actually going to remove my cryptic RLE encoding and return to normal 3D array semantics using blists!

Run Length Encoding in Python

Posted in Development, How To, Programming with tags , , , on 2011/06/10 by Adam Griffiths

The following code is my implementation of RLE in Python. I’ve included a method to modify values without having to decode the entire value.

Please note that this algorithm is inferior to the RLE with Positioning I posted about here.

Position Aware Run Length Encoding in Python

Posted in Development, How To, Programming with tags , , , on 2011/06/10 by Adam Griffiths

I mentioned previously wanting to improve the RLE to include position information. I’m sure it’s already got a name, but I’m going to call it Position Aware RLE (PARLE).

Below is the code I’ve written to accomplish this. I’m sure someone can come up with a more concise way of writing it, but this is the best I can do at the moment.

Creating Voxel Volumes Quicky in Python

Posted in Development, How To, Programming with tags , , , on 2011/06/09 by Adam Griffiths

Creating large chunks of memory is quite tricky in Python because of a number of overheads. I’ve been attempting this myself and have found a fast method to do this which combines a few handy optimisations we would need later on for a Voxel Engine anyway.

Please be aware that the code evolves along the way, so don’t blindly copy and paste the first examples =).

Also, the WordPress theme is cutting of some text. If you copy and paste it, it is still there.

This post is continued in Position Aware RLE, RLE and Part 2.

Building PyBullet on Windows

Posted in How To, Programming with tags , , , on 2011/05/24 by Adam Griffiths

PyBullet is a wrapper around the popular Bullet C++ physics library.

Once you’ve build the C++ Bullet library you can then build PyBullet.

The PyBullet documentation states to use the –include-dirs directive to add the Bullet include path, but it also requires the numpy include directory which didn’t resolve automatically for me. Unfortunately you can’t just append it to the –include-dirs flag.

I resolved it with the following:

cd path\to\PyBullet

set INCLUDE=%INCLUDE%;c:\path\to\python\site-packages\numpy\core\include

python setup.py build_ext –include-dirs c:\path\to\bullet\src –library-dirs c:\path\to\bullet\msvc\2008\lib\Release

Obviously you replace the \msvc\2008 directory with the appropriate one if you didn’t build the vanilla target.

After this, copy the file PyBullet\build\lib.win32-2.6\bullet\bullet.pyd to PyBullet\bullet.

Include the PyBullet\bullet directory in your Python project and import.

You should now be able to do the following:

import bullet.bullet as bullet

print help(bullet)

Telstra BigPond Thompson Modem and Killing Floor

Posted in Uncategorized with tags , , , on 2011/03/17 by Adam Griffiths

The Thompson modem used by Telstra (and On2 and BT) creates a unique issue with Killing Floor. I documented this on the Steam forums but it doesn’t appear to have gotten much attention so I thought I would reproduce it below.

Edit: There is now an “official” fix on the Steam forums, but I cannot verify if it resolves these issues.