Thursday, September 1, 2011

Building opencv on win32 with mingw and cmake


I will be logging my successful attempt at building opencv 2.3.1 on windows with mingw.

Rationale:
1. The binaries provided with opencv superpack fail, requiring a mysterious libstdc++-6.dll
2. I have to build a robot. NOW.

Steps to reproduce success:
1. Download opencv superpack
2. Download nuwen mingw because it is the most complete mingw `distro' out there (includes SDL, latest gcc and boost goodness!)
4. Start cmd.exe, not msys.
5. Type in set PATH=mingwdir\bin;cmakedir\bin

where mingwdir and cmakedir are full paths to mingw and cmake installation locations.

The reason I resetted PATH variable is because you don't need any other paths in your current cmd.exe session in order to build opencv. Other systems such as msysgit can interfere with your build, causing cmake to fail. Which is what happened in my case.

6. Extract opencv and go to opencv root dir.
7. execute the command: cmake -G "MinGW Makefiles" -D CMAKE_MAKE_PROGRAM:string="mingwdir\bin\make.exe" .

Of course you can specify target dir, lib dir etc. I'm just giving this as an example to get over the problem that cmake can't find your make executable unless you tell it specifically with this variable.

The dot at the end means "current directory" where your opencv CMakeLists.txt resides.

8. Execute make

Hope this will be useful for me in the future when I forget how to do things.

End of log.

Wednesday, December 16, 2009

Interesting Libraries Series #2

Today's interesting libraries

C++



Hiberlite

Link
http://code.google.com/p/hiberlite/


Properties
Cross-Platform

Synopsis
Provides a lazy interface to sqlite databases. Provides ORM capability using macros and boost.serialization library.

Boost.Rdb

Link
http://code.google.com/p/boost-rdb/

Cross-Platform

Synopsis
Boost based database access library. Provides ORM capability and syntax like linq.
This might, in the future, become the de-facto standard C++ database library.

End of log

Tuesday, December 8, 2009

Interesting Libraries Series #1

Today's interesting libraries

C++


UTF8-CPP

Link
http://utfcpp.sourceforge.net

Properties
Cross-Platform
Header-Only
Iterator-Based

Synopsis
Provides conversions between UTF-32, UTF-16 and UTF-8. Doesn't have its own string types. Validates UTF-8 sequences.

RapidXML

Link

http://rapidxml.sourceforge.net

Properties
Cross-Platform
Header-Only
Iterator-Based

Synopsis
Very fast parser. Optimized with memory pools. Boost.PropertyTree library uses it as its default xml parser.

End of log

Wednesday, August 19, 2009

How to create a Visual C++ DLL for implicit linking

I will be logging how to create a dynamic link library (DLL) for implicit linking.

See MS documentation on DLLs for further information.

Problems encountered:
----------------------------

* dll file wasn't getting generated.
* lib file (import library) wasn't getting generated.

Solutions:
---------------

To get the dll file generated, just set the Project/Properties/Configuration Properties/Linker/General/Output File manually.

To get the lib file generated, use __dllspec(dllexport) on classes and functions like this:

void __dllspec(dllexport) f(){}
class __dllspec(dllexport) wtf{};

To generate a static build, use __dllspec(dllimport) instead.

End of log.

Monday, August 10, 2009

Twitter

I'm on twitter now. Watch me fail at using it here:

http://twitter.com/the_epitaph

Wednesday, May 27, 2009

Pseudo-Partial-Function-Template-Specialization in C++

In thist post, I will be logging a simple technique to create Pseudo-Partial-Function-Template-Specialization (PPFTS?) in C++.

Rationale:
* PFTS is a nice thing to have.
* The C++ standard currently does not allow it
* The next C++ standard (C++0x) will allow it, but that's a long time from now.

Motivating example:
bool ok= false;

std::string strx;
XType t= convert<XType>(strx, ok);

std::string stry= convert<std::string>(42, ok);

char const[] cstr= "123.12";
double dbl= convert<double>(cstr, ok);


Being able to specialize convert partially, allowing only one specialization for std::string to act on all types, and so on.

Implementation:

Simply partial specialize a struct with a static member function and call it from the template function.


template <typename From, typename To>
struct Converter
{

static To convert(From const &from, bool &ok)

{
To to;
std::stringstream converter;

converter<< from;
ok= converter>> to;
return to;

}
};

template <typename To>
struct Converter<std::string, To>

{
static To convert(std::string const &from, bool &ok)

{
To to;
std::istringstream converter(from);

ok= converter>> to;
return to;
}
};

template <>
struct Converter<char const*, int>
{

static int convert(char const* from, bool &ok)

{
int to= 0;
ok= std::sscanf(from, "%d", &to)> 0;

return to;
}
};

template <typename From, typename To>

To convert(From &from, bool &ok)
{
To nrvo= Converter<From, To>::convert(from, ok);

return nrvo;
}


No overloads. End of log.

Thursday, September 11, 2008

Do The Same Series 1 - XmlDocument VERSUS libcurl && libxml++2

In the "Do The Same Series", I am going to explore programming tasks which I perform in C#.NET and try to compare them with C++ alternatives, often involving third party libraries. This will probably end up being the only entry in the series.

This post is about downloading and querying very specific regions of an xml document easily using xpath. I am going to use the url of an xml file which has currency rates.

C#.NET:

XmlDocument xml_document= new XmlDocument();
xml_document.Load("http://www.tcmb.gov.tr/kurlar/today.xml");
String xpath= "/Tarih_Date/Currency[@CurrencyCode='USD']/BanknoteBuying";
XmlNode node= xml_document.SelectSingleNode(xpath);
String value= node.InnerText; // gives me the current $/YTL ratio

Very few lines of code and almost no margin of error. I like C#.NET.

C++ (and libcurl and libxml++2):

There is no short way of doing this. The C++ wrapper for libcurl just introduces overhead with no useful facilities. So I will introduce a few of my own.

The C API of curl is very sane, giving great flexibility to programmers with C style callbacks. I won't spend time wrapping them to use member functions and such. The function callbacks are ok for now.

There are two curl options of interest here:
CURLOPT_WRITEDATA:
The option which tells curl where the write function will output its data. The default is stdout.
CURLOPT_WRITEFUNCTION:
The option which tells curl which funciton to call when it needs to write downloaded data. The default is a function which writes to a file.

So I can change the writedata to a C++ container and the writefunction to something which appends to that container. I will also write a simple function which takes a url and puts it into the given container.

namespace pwned{ namespace curl
{
template <typename containerT>
std::size_t output_to_container(void* data, std::size_t size, std::size_t nmemb, void* input)
{
containerT* con= static_cast<containerT*>(input);
char* cstr= static_cast<char*>(data);
std::size_t len= size* nmemb;
// insert will work on any sequence including std::string
try { con-> insert(con-> end(), cstr, cstr+ len); }
catch(...) { return CURLE_WRITE_ERROR; }
return len;
}

template <typename containerT>
void set_output_container(CURL* c, containerT &s)
{
curl_easy_setopt(c, CURLOPT_WRITEDATA, &s);
std::size_t(*f)(void*, std::size_t, std::size_t, void*)= output_to_container<containerT>;
curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, f);
}

template <typename containerT>
void url_to_container(std::string const &url, containerT &c)
{
CURL* curl= curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
pwned::curl::set_output_container(curl, c);
curl_easy_perform(curl);
curl_easy_cleanup(curl);
}

} // curl
} // pwned

Now, on to xml parsing. The library I chose was libxml++2, a very nice C++ wrapper for libxml2. The only sin of libxml2 is that it can't validate xml, but we are not bothered with schemas right now. The point is, it provides xpath search and can use utf-8 strings from glibmm, so it is as close as they get to .NET's functionality. It is also very accessible on windows and linux. (accompanies gtkmm on win32)

std::string xml;
pwned::curl::url_to_container("http://www.tcmb.gov.tr/kurlar/today.xml", xml);
xmlpp::DomParser parser;
parser.parse_memory(xml);
std::string xpath= "/Tarih_Date/Currency[@CurrencyCode='USD']/BanknoteBuying";
xmlpp::NodeSet nodes= parser.get_document()-> get_root_node()-> find(xpath);
xmlpp::Element* element= dynamic_cast<xmlpp::Element*>(nodes.at(0));
std::string value= element-> get_child_text()-> get_content();

On my linux distro I could build and run the test program using:
g++ test.cpp `pkg-config libcurl libxml++2 --cflags --libs` && ./a.out

See you next time, should there be one.

Saturday, May 10, 2008

Impersonating users on ASP.NET login is easy

Rationale:

I had to write a web interface for controlling a windows service on a server using VS2008, but it took me a few hours of research. So I thought I'd log my experiences.

Problems:

Website user authentication faking a windows authentication account.
VS2008 not giving access to global.asax file.

Solutions:

First of all, the way I chose to do this was to create an asp.net page with a login control.
1) I created a role (AWESOME)
2) I created a user associated with that role (ASPUSERNAME)
Don't forget to add a reference to System.ServiceProcess

So the layout is like:

<loginview>
<anonymoustemplate>
<login>
</login>
</anonymoustemplate>
<rolegroups>
<rolegroup roles="AWESOME">
<contenttemplate>
<start button="btnStart" />
<stop button="btnStop" />
</contenttemplate>
</rolegroup>
</rolegroups>
</loginview>

On Page_Load I did:

control= new ServiceController("serviceName");

On btnStart_Clicked I did:

control.Start(); // try/catch

On btnStop_Clicked I did:

control.Stop(); // try/catch

In web.config I did:

<authorization>
<allow users="ASPUSERNAME" />
</authorization>

<authentication mode="Forms" />

<rolemanager enabled="true" />

<identity impersonate="true" username="MACHINE\USER" password="PASSWORD" />

(yes, single '\')

Now if you coded everything correctly, your project most likely won't build, and give you an error like:

Failed to start monitoring changes to SOMEPATH global.asax because access is denied

You just have to start VS2008 as administrator. All done.

Friday, January 18, 2008

Compiling and using Qt4.3.3 with mingw g++ 4.2

I will be logging my attempt at compiling and using Qt opensource 4.3.3 using mingw.
I got mingw from http://nuwen.net/mingw.html

Reasons to compile:
==============

  1. Qt opensource 4.3.3 binaries aren't ABI compatible with g++ 4.2 on my mingw distro, so you get linker errors when building.
  2. Rebuilding Qt with required parameters.
Problems encountered:
=================

  1. Qt 4.3.3 sources had missing forward declarations.
  2. Environment variables caused header file confusion.

Compilation:
=========

Extract the package and make sure its \bin directory is in PATH.

I got the latest Qt opensource release from here.

Extract the sources.

Start cmd.exe and move to the source directory.

On my platform, the INCLUDE environment variable had the Platform SDK directory,
so Qt build system was finding the wrong Windows.h. To clean things up, I did:

set include=
set lib=

Qt 4.3.3 sources actually had a couple of errors. For this version I had to do the following:

Edit \src\corelib\kernel\qeventdispatcher_win.cpp
A forward declaration is missing. Add it after the #includes:

LRESULT CALLBACK qt_internal_proc(HWND, UINT, WPARAM, LPARAM);

Edit \src\gui\inputmethod\qwininputcontext_win.cpp
A forward declaration is missing. Add it after the #includes:

bool qt_sendSpontaneousEvent(QObject*, QEvent*);

Run

configure.exe -platform win32-g++

and any additional parameters you would like with configure.
That should give you a Makefile.

This will be a long compilation, I've used:

make -j 3

In my case this process resulted in debug and release shared
libraries and import libraries in \lib and \bin directories.

Note:
====

The qmake which is built by this process will have the build directory hardcoded,
so make sure that you build it in the correct directory.

Friday, November 23, 2007

SQLite 3 on windows with mingw and vc2005

I will be logging my attempt to make use of SQLite 3 on windows.

If you want to write programs and link them to sqlite using mingw or msvc, first you need to download the binaries from sqlite's website: http://sqlite.org/download.html

Download the dll binary, extract it somewhere.
You will find one .dll and one .def file.

The def file and the dll file together can be used to create an import library on windows.
There are two ways of accomplishing this. Using msvc or using mingw.

With msvc:
==========
1) Start a visual studio 2005 command prompt, move to our directory.
2) Give the command: lib /def:sqlite3.def /machine:X86
(your machine may vary)

With mingw:
===========
1) Edit sqlite3.def and to the beginning add: LIBRARY sqlite3.dll ( otherwise the import library won't know what dll it requires at runtime, default is (null).dll )
2) Issue command: dlltool -d sqlite3.def -l libsqlite3.dll.a
3) You won't even need an import library anyway, since the linker can use a dll directly.

Note:
=====
If you issue: g++ prog.cpp -l sqlite3
First, a libsqlite3.dll.a is searched for.
Then a libsqlite3.a is searched for.
Then sqlite3.dll will be searched for.
Sometimes mingw can't link dlls. I don't know the details, but it worked for me in this case.

Note:
=====
If you already have a vc2005 .lib file, you can just rename it to libsqlite3.dll.a and use it with mingw. There are no symbol name mangling conflicts thanks to extern "C".

Header File:
============
Now all you need is the sqlite3.h file. It is standalone and only includes C headers. It can be found within the sqlite source download or the cvs. Mine was named sqlite3.h.in, I just renamed it and copied it over.

Now for some sqlite3:
=====================


#include <sqlite.h>
#include <iostream>
#include <string>
int main()
{
sqlite3* db;
int result= sqlite3_open("test.db", &db);
if(result!= SQLITE_OK) { std::cerr<< "Error opening test.db\n"; return 1; }
sqlite3_stmt* s;

std::string q= "create table isimler(no int, ad text, soyad text)";
sqlite3_prepare_v2(db, q.c_str(), q.size(), &s, 0);
sqlite3_step(s);
sqlite3_reset(s);

q= "insert into isimler(no, ad, soyad) values(?, :ad, :soyad)";
sqlite3_prepare_v2(db, q.c_str(), q.size(), &s, 0);
int no= 1; std::string ad= "nurettin ali", soyad= "berkol";
sqlite3_bind_int(s, 1, no);
sqlite3_bind_text(s, 2, ad.c_str(), ad.size(), SQLITE_STATIC);
sqlite3_bind_text(s, 3, soyad.c_str(), soyad.size(), SQLITE_STATIC);
sqlite3_step(s);
sqlite3_reset(s);

no= 2; ad= "yesari asim"; soyad= "arsoy";
sqlite3_bind_int(s, 1, no);
sqlite3_bind_text(s, 2, ad.c_str(), ad.size(), SQLITE_STATIC);
sqlite3_bind_text(s, 3, soyad.c_str(), soyad.size(), SQLITE_STATIC);
sqlite3_step(s);
sqlite3_reset(s);
sqlite3_clear_bindings(s);

q= "select no, ad, soyad from isimler";
sqlite3_prepare_v2(db, q.c_str(), q.size(), &s, 0);
while(sqlite3_step(s)== SQLITE_ROW)
std::cout
<< sqlite3_column_int(s, 0)<< " | "
<< sqlite3_column_text(s, 1)<< " | "
<< sqlite3_column_text(s, 2)<< "\n";

sqlite3_finalize(s);
sqlite3_close(db);
}

Sunday, October 7, 2007

Building SDL from cygwin using mingw (no stdio redirection)

I will be logging my successful attempt at building SDL from cygwin using mingw on windows vista.
The process was simple enough, the only thing you need to do is to install mingw properly and give correct parameters to the configure script.

Install mingw. I used the mingw distro from http://nuwen.net/mingw.html
Set up PATH as described and make sure gcc -dumpversion works properly when you open a commandline.

At the time of writing this, the output was:
4.2.1-dw2
Install a minimal cygwin.
Start cygwin commandline and make sure gcc -dumpversion gives the same result.
Download and extract SDL sources from http://libsdl.org
In the cygwin commandline, move to the directory SDL sources are.
Make a build directory as usual, so that our attempt remains separate from other building attempts and we won't have to clean up the next time we build from this source.

Something like:
mkdir cygwinmingwbuild
Now move into that directory and if you want to build SDL without stdio redirection, type:
../configure --build=i686-pc-mingw32 --host=i686-pc-mingw32 --enable-stdio-redirect=no
And any other flags that you desire, but try not to break the build at your first try. Omit the --enable flag if you want redirection.
Hopefully your system is fast enough and you won't get "out of synch" errors from cygwin.
Don't mind if you get a warning about configure.in being old, and you will get the static and shared libraries under:

cygwinmingwbuild/build
cygwinmingwbuild/build/.libs

From these directories you need:
libSDLmain.a
libSDL.a
libSDL.dll.a
SDL.dll

libSDL.dll.a is searched by default if you aren't statically linking.
libSDL.a is for -static linking

You may want to
strip libSDL*
strip SDL.dll
upx SDL.dll
If you want smaller binaries, but that's not going to speed anything up.

Sunday, September 23, 2007

boost::function and SDL timer callbacks:

I will be describing how to wrap SDL timer callback API using boost.function.
Thankfully, after version 1.2.7, SDL timer callback signature has a void* where you can pass any kind of data. Same applies to most sane C APIs. But of course C++ programmers also require type safety and the ability of passing member functions as callbacks.

A simple solution would be:


typedef boost::function<void()> f_type;

Uint32 add_timer_helper(Uint32 interval, void* p)
{
f_type* fp= static_cast<f_type*>(p);
(*fp)();
return interval;
}

SDL_TimerID add_timer(f_type const &f, Uint32 interval)
{
SDL_TimerID id= SDL_AddTimer(interval, add_timer_helper,
const_cast<void*>(static_cast<void const*>(&f)));
return id;
}


However, this requires you to store a boost::function instance and keep it alive until it is no more called. Since it is not practical to change the value of this stored boost function, we can store the added boost function callbacks somewhere and not care about them.

Since we don't want to store them by copy and we want to erase the function by timer id, it is a logical choice to store them in a boost::ptr_map. I placed this map inside a class. It probably needs to go into a singleton, but that's up to the reader.



#include <iostream>
#include <ostream>
#include <cstdlib>
#include <cassert>
#include <map>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/ptr_container/ptr_map.hpp>
#include <SDL.h>

namespace
{

struct sdl_timer
{
typedef boost::function<void()> f_type;
typedef boost::ptr_map<SDL_TimerID, f_type> cb_map;
cb_map cb;

static Uint32 add_timer_helper(Uint32 interval, void* p)
{
f_type* fp= static_cast<f_type*>(p);
(*fp)();
return interval;
}

SDL_TimerID add(f_type const &f, Uint32 interval)
{
f_type* fp= new f_type(f);
SDL_TimerID id= SDL_AddTimer(interval, add_timer_helper, fp);
cb.insert(id, fp);
return id;
}

void remove(SDL_TimerID id)
{
SDL_RemoveTimer(id);
cb.erase(id);
}

void change(f_type const &f, Uint32 interval, SDL_TimerID &id)
{
remove(id);
id= add(f, interval);
}
} timer_api;

}

struct wtf
{
SDL_TimerID id1, id2;
void f(){ std::cout<< "wtf::f()"<< std::endl; }
void g(){ std::cout<< "wtf::g()"<< std::endl; }
void h(){ std::cout<< "wtf::h()"<< std::endl; }
};

int main(int, char*[])
{
std::ios::sync_with_stdio(false);
int err= SDL_Init(SDL_INIT_TIMER| SDL_INIT_VIDEO);
assert(err== 0);
SDL_Surface* vid= SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);
assert(vid!= 0);
wtf w;
w.id1= timer_api.add(boost::bind(&wtf::f, &w), 1000);
w.id2= timer_api.add(boost::bind(&wtf::h, &w), 1000);
SDL_Delay(2000);
timer_api.change(boost::bind(&wtf::g, &w), 1000, w.id1);
SDL_Delay(2000);
timer_api.remove(w.id1);
timer_api.remove(w.id2);
SDL_Quit();
return EXIT_SUCCESS;
}



So now we can add and remove timers as well as switch callback functions.

Saturday, September 15, 2007

#define dependent lines in C++

This is an attempt at creating a macro dependent scope using boost preprocessor. The lines within this scope won't be executed unless a certain macro is defined. I also introduced a small macro to log expressions if NDEBUG is not defined.

Note that any expression which has a comma in it will be processed as separate macro arguments, so the parenthesis around such an expression is neccessary. I did all this because I thought

#ifdef MACRO
specific code here
#endif

Scopes, in my opinion, looked ugly compared to
DEBUG_CODE
(
specific code here
)



#include <iostream>
#include <ostream>
#include <iomanip>
#include <ios>

#include <boost/preprocessor/stringize.hpp>
#include <boost/preprocessor/facilities/is_empty.hpp>
#include <boost/preprocessor/control/if.hpp>

#define MACRO_DEPENDENT(m, c) \
BOOST_PP_IF(BOOST_PP_IS_EMPTY(m),,c)

#define DEBUG_CODE(l) \
MACRO_DEPENDENT(NDEBUG,l)

#define CLOG_EXPR(v) \
(::std::clog \
<< ::std::boolalpha \
<< ( "( " BOOST_PP_STRINGIZE(v) " ) = " ) \
<< (v) \
<< ::std::endl);

#define DEBUG_CLOG_EXPR(c) \
DEBUG_CODE(CLOG_EXPR(c))

int main()
{
int n= 42;
#define NDEBUG
DEBUG_CODE
(
(std::cout<< "This will not show up"<< std::endl);
)
#undef NDEBUG
DEBUG_CLOG_EXPR(n + 42)
DEBUG_CODE
(
(std::cout<< "DEBUG_CODE, line 1"<< std::endl); // beware the comma
(std::cout<< "DEBUG_CODE, line 2"<< std::endl);
)
}

Tuesday, August 21, 2007

How to set up gtkmm on windows vista easily:

I will be logging how to set up gtkmm for programming on windows vista. This will only work on a win32 platform.

To install gtkmm, first you need the gtk+ development libraries.
Latest version can be found in the sourceforge archives.
And install it.

Next you need the gtkmm development libraries.
Latest version can be found on the gnome ftp site.
And install it to the default directory. It should default to the place you installed gtk+.

Working with MinGW and gtkmm from the commandline in Windows Vista:

I use the mingw distro from nuwen.net
Just install it to C:\MinGW and add C:\MinGW\bin to your PATH variable.

Now if you want to get gtkmm to work from the commandline, you need to set up your PKG_CONFIG_PATH.
The value should be (install path)\lib\pkgconfig where all the *.pc files are.

Start a new command prompt and you should be able to get the output from
pkg-config --list-all
Find the latest gtkmm version from that list, mine was gtkmm-2.4 so I used:
pkg-config gtkmm-2.4 --cflags --libs

This gave me all the include/linker flags neccessary to build gtkmm programs.


Sunday, August 19, 2007

Open Dynamics Engine (ODE) basics:

I am logging the basics I learned about using ODE in my programs which need rigid body physics. I encountered a few problems when reading online tutorials and documentation, so I decided to write my own introduction to ODE. As you read this introduction, you need to keep the documentation open.

The documentation had a list of steps the programmer needs to take in order to write a typical simulation, but I had to jump around in the documentation as I tried to gather the functions to accomplish these steps.

For a typical simulation, it is a good idea to use ODE in this manner:

//Create a physics world.
dWorldID world= dWorldCreate();

//Create bodies in the world.
dBodyID ball= dBodyCreate(world);

/*Note:
A body is used for associating a mass with a geometry. If you don't set a geometry's body, it will have a body without a custom mass. I don't know the specifics of what kind of mass a geometry has by default. Perhaps none.
*/

//Create masses for the bodies.
dMass ball_mass;
dMassSetSphereTotal(&ball_mass, 10, 40);
dBodySetMass(ball, ball_mass);

/*Note:
When body masses are set, they will be affected by gravity, momentum and impulse during simulation steps.

The documentation does not mention units of mass here.

Search the documentation for dMassSet* to see what kinds of masses you can apply to bodies and how you can rotate/translate them.
*/

//Create a collision space.
dSpaceID collision_space= dSimpleSpaceCreate(0);

/*Note:
See documentation for other space create functions.
*/

//Create geometries for the bodies in the collision space.
dGeomID ball_geom= dCreateSphere(collision_space, 40.f);

//Create geometries which aren't attached to any body as needed, also in the //collision space.
dGeomID platform_geom= dCreateBox(collision_space, 100.f, 40.f, 0.f);

/*Note:
See documentation for other dCreate* functions
*/

//You need to set the starting positions.
dGeomSetPosition(ball_geom, 320.f, 50.f, 0.f);
dGeomSetPosition(platform_geom, 320.f, 430.f, 0.f);

/*Note:
This function puts the geometry into a position where the geometric middle stands on the given arguments. ODE knows the geometric middle of predefined geometries.
*/

//You need to set error reduction and constraint force mixing parameters.
dWorldSetERP(0.9);
dWorldSetCFM(0.00001);

/*Note:
The documentation details these functions If you set them to these extremes, the simulation may not behave correctly. If you set them to more normalized values, the simulation becomes sluggish and inexact. Which also means it won't behave correctly. In short, you need to tweak until you get something similar to what you want.
*/

//If needed, set the gravitational acceleration vector. All masses will accelerate.
dWorldSetGravity(world, 0.f, -9.81f, 0.f);

/*Note:
Now the world has a ball, a 2D box and approximately earth's acceleration. Gravity won't affect the box, because it is just a geometry and has no body. So it is just a platform hanging there. Its only effect is to provide a static rigid body for collisions. How to do collisions follows.
*/

//Create a contact joint group.
dJointGroupID contact_joint_group= dJointGroupCreate(0);

/*Note:
joint group is a container of joints. You can add joints into it, or empty it. This will be useful for storing contact joints which just give the collision dynamics effect.
*/

//Apply a collision callback function to every geometry in the space which is //likely to collide.
dSpaceCollide(collision_space, void_pointer_parameter, collision_callback);

/*Note:
The other option was to call dCollide for every geometry in space, which would end up with
*/

Inside the callback function, you prepare a number of contact informations and check if two geometries collided. If they did, the information will be pushed into the contact informations.

signature:
void (*)(void* p, dGeomID g1, dGeomID g2)
inside:
dContact contacts[10];
for(int i= 0; i<>
{
contact[i].surface.mode = dContactBounce;
contact[i].surface.mu = .0f;
contact[i].surface.bounce = .5f;
contact[i].surface.bounce_vel = .0f;
}

Each contact is bouncy, has a surface friction of 0, things which bounce off this surface will retain half their energy and the minimum velocity for bouncing off each contact is 0. If you don't set bounce_vel for each potential contact, your colliding body probably won't bounce. This was not done in one of the tutorials, so nothing bounced when I tried getting the code to work.

int n_contacts= dCollide(g1, g2, 10, &contact[0].geom, sizeof(dContact));

This will figure out how many contact points exist in between the geometries g1 and g2. sizeof(dContact) is the number of bytes between the address of each contiguous contact's geometries. They probably left this function relaxed so that the collision data structure is customizable.

Joints are attached between bodies, so we get the bodies of the geometries.
dBodyID b1= dGeomGetBody(g1);
dBodyID b2= dGeomGetBody(g2);

for(int i= 0; i<>
{
dJointID contact_joint=
dJointCreateContact( WORLDID, CONTACT_JOINT_GROUP, &contact[i])
dJointAttach(contact_joint, b1, b2);
}

The world ID and contact joint group ID somehow need to be passed into this function. It is up to the programmer to make use of the void* parameter of the callback or global variables.

So dSpaceCollide called the collision callback for potential collisions, which checked if the geometries really collided and if they did, got the contact information, which is used to create contact joints in the contact group.

Next action is to take a simulation step.

dWorldStep(0.03);

See the world step functions for details on the argument and other function choices.

So the simulation will happen with the contact joints connected to some bodies. The forces will be applied, etc. If the joints remain connected when you take another simulation step, the bodies will remain attached and won't be able to separate. Se after taking a simulation step, the contact joints must be removed.

Easiest way is to empty the contact joint group:

dJointGroupEmpty(contact_joint_group);

And so on. Continue stepping the simulation with these three functions:
dSpaceCollide(collision_space, void_pointer_parameter, collision_callback);
dWorldStep(n);
dJointGroupEmpty(contact_joint_group);

Every step, the geometry coordinates can be accessed:
dReal const* ball_pos= dGeomGetPosition(ball_geom);

This log ends here. I will post a complete example if neccessary.

code::blocks on debian lenny

I am logging my attempt at creating binary packages for code::blocks svn build 4402. This will only work for i386 and amd64 architectures.

Problems I encountered:
  • g++-4.1 segfaulted (ICE) on a certain file. It is a reproducable bug which I was too lazy to file. So use g++-4.2, it is in lenny.
  • Package dependencies weren't set up correctly, I had to edit debian build scripts. The build will stop with a missing header if you try to build with wxgtk2.6.

You need the codeblocks sources. This page shows how to check out the svn repository.

svn checkout svn://svn.berlios.de/codeblocks/trunk

Then edit the debian/control script under trunk. Change all:
libwxgtk2.6-dev -> libwxgtk2.8-dev
libstdc++6-4.0-dev -> libstdc++6-4.2-dev

Debian lenny or sid don't have wxgtk2.8, wxwidgets website tells you to add this repository to your apt sources:
deb http://apt.tt-solutions.com/debian/ etch main

edit /etc/apt/sources.list to add this line. The page also shows an ubuntu repository for the library.

Now update:
sudo aptitude update

You need these installed:
sudo aptitude install libwxgtk2.8-dev devscripts libtool autoconf g++-4.2 -y

Make sure your g++ symlink points at g++-4.2
ls -l /usr/bin/g++

If it shows g++-4.1, remove the symlink and make it point at g++-4.2:
sudo rm /usr/bin/g++
sudo ln -s /usr/bin/g++ /usr/bin/g++-4.2

Now start building. First bootstrap (create configure script, etc.) then build debs.
./bootstrap
debuild

This took a long time on my single processor amd64 box, but it completed. Not bad for amd on summer. Now go to the directory above and install the packages.
cd ..
sudo dpkg -i *deb

And you're most likely done.