碰撞效果 in ODE

首先是结果,两个球碰撞,有重力

大概是这种感觉:

               b1↓

                b2↓

gggggggggggggggg

碰撞过后:

  ←b1  b2→
ggggggggggggg

直接用opengl画出来不是不可以

不过那样的话大量描画代码就把本身重点的东西给遮住了.

要导入glfw,gl,glu,几十行代码下来,就很难分清楚那些是ode的代码了.

因此数据才是硬道理

另外这个可以通过gnuplot写个循环来实现动画效果... 那样很好玩, 比如这样:



下面是数据

ball0 0.0000000.0000002.159022ball10.2000000.0000000.219847
ball0 0.0000000.0000002.034562ball10.2000000.0000000.227990
ball0 0.0000000.0000001.909122ball10.2000000.0000000.235153
ball0 0.0000000.0000001.782702ball10.2000000.0000000.241336
ball0 0.0000000.0000001.655303ball10.2000000.0000000.246540
ball0 0.0000000.0000001.526923ball10.2000000.0000000.250763
ball0 0.0000000.0000001.397563ball10.2000000.0000000.254006
ball0 0.0000000.0000001.267223ball10.2000000.0000000.256269
ball0 0.0000000.0000001.135903ball10.2000000.0000000.257553
ball0 0.0000000.0000001.003604ball10.2000000.0000000.257856
ball0 0.0000000.0000000.870324ball10.2000000.0000000.257179
ball0 0.0000000.0000000.736064ball10.2000000.0000000.255522
ball0 0.0000000.0000000.600824ball10.2000000.0000000.252886
ball0 0.0000000.0000000.464604ball10.2000000.0000000.249269
ball0 -0.0261940.0000000.383820ball10.2261940.0000000.188257
ball0 -0.0698740.0000000.346906ball10.2332210.0000000.190496
ball0 -0.1143260.0000000.307516ball10.2418150.0000000.193253
ball0 -0.1594500.0000000.265052ball10.2523560.0000000.197122
ball0 -0.2045740.0000000.221609ball10.2628980.0000000.200011
ball0 -0.2496980.0000000.177186ball10.2734400.0000000.201920
ball0 -0.3036170.0000000.181699ball10.2839820.0000000.202850
ball0 -0.3575380.0000000.185359ball10.2945240.0000000.202799
ball0 -0.4114590.0000000.188287ball10.3050660.0000000.201768
ball0 -0.4653800.0000000.190629ball10.3156070.0000000.199757
ball0 -0.5193010.0000000.192503ball10.3261490.0000000.199803
ball0 -0.5732220.0000000.194002ball10.3366910.0000000.199841
ball0 -0.6271430.0000000.195201ball10.3472330.0000000.199872
ball0 -0.6810640.0000000.196160ball10.3577750.0000000.199897
ball0 -0.7349850.0000000.196927ball10.3683170.0000000.199916
ball0 -0.7889060.0000000.197541ball10.3788590.0000000.199932
ball0 -0.8428270.0000000.198032ball10.3894000.0000000.199945
ball0 -0.8967480.0000000.198425ball10.3999420.0000000.199955
ball0 -0.9506690.0000000.198739ball10.4104840.0000000.199963
ball0 -1.0045900.0000000.198990ball10.4210260.0000000.199969
ball0 -1.0585110.0000000.199191ball10.4315680.0000000.199974
ball0 -1.1124320.0000000.199352ball10.4421100.0000000.199979
ball0 -1.1663530.0000000.199481ball10.4526520.0000000.199982
ball0 -1.2202740.0000000.199584ball10.4631930.0000000.199985
ball0 -1.2741950.0000000.199666ball10.4737350.0000000.199987
ball0 -1.3281160.0000000.199732ball10.4842770.0000000.199988
ball0 -1.3820370.0000000.199784ball10.4948190.0000000.199990
ball0 -1.4359580.0000000.199827ball10.5053610.0000000.199991
ball0 -1.4898790.0000000.199860ball10.5159030.0000000.199992
ball0 -1.5438000.0000000.199887ball10.5264450.0000000.199992
ball0 -1.5977210.0000000.199909ball10.5369860.0000000.199993
ball0 -1.6516420.0000000.199926ball10.5475280.0000000.199993
ball0 -1.7055630.0000000.199940ball10.5580700.0000000.199994
ball0 -1.7594840.0000000.199951ball10.5686120.0000000.199994
ball0 -1.8134050.0000000.199960ball10.5791540.0000000.199994
ball0 -1.8673260.0000000.199967ball10.5896960.0000000.199994
ball0 -1.9212470.0000000.199972ball10.6002380.0000000.199995
ball0 -1.9751680.0000000.199977ball10.6107790.0000000.199995
ball0 -2.0290890.0000000.199981ball10.6213210.0000000.199995
ball0 -2.0830100.0000000.199984ball10.6318630.0000000.199995
ball0 -2.1369310.0000000.199986ball10.6424050.0000000.199995
ball0 -2.1908520.0000000.199988ball10.6529470.0000000.199995
ball0 -2.2447730.0000000.199989ball10.6634890.0000000.199995
ball0 -2.2986940.0000000.199990ball10.6740310.0000000.199995
ball0 -2.3526150.0000000.199991ball10.6845720.0000000.199995
ball0 -2.4065360.0000000.199992ball10.6951140.0000000.199995



最后是代码:


Mac-mini:ode$ cat example2.d
import std.stdio;
import ode;

static dWorldID world;
static dSpaceID space;
static dGeomID ground;
static dJointGroupID contactgroup;

const dReal radius = 0.2;
const dReal mass = 1.;

struct obj{
	dBodyID b;
	dGeomID geom;
}

obj[] ball;

extern(System) void nearCallBack(void* date, dGeomID o1, dGeomID o2){
	const int N = 10;
	dContact[N] contact;
	int n = dCollide(o1,o2,N,&contact[0].geom,dContact.sizeof);
	for(int i=0;i<n;i++){
		with (contact[i].surface){
			mode = dContactBounce;
			mu = dInfinity;
			bounce = 0.;
			bounce_vel = 0.;
		}
		dJointID c = dJointCreateContact(world, contactgroup, &contact[i]);
		dJointAttach(c, dGeomGetBody(contact[i].geom.g1), dGeomGetBody(contact[i].geom.g2));
	}
}

void simLoop(){
	dSpaceCollide(space, null ,&nearCallBack);
	dWorldStep(world, 0.01);
	dJointGroupEmpty(contactgroup);
	dReal* pos;
	foreach(k,b;ball){
		pos = dBodyGetPosition(b.b);
		write("ball",k,"\t");
		foreach(i;0..3) writef("%.6f\t",*(pos+i));
	}
	writeln();
}

void main(){
	dInitODE();
	world = dWorldCreate();
	space = dHashSpaceCreate(null);
	contactgroup = dJointGroupCreate(0);

	dWorldSetGravity(world, 0, 0, -9.8);
	ground = dCreatePlane(space, 0,0,1,0);
	ball ~= 
	* new obj(dBodyCreate(world), dCreateSphere(space, radius));
	dMass m1;
	dMassSetZero(&m1);
	dMassSetSphereTotal(&m1,mass,radius);
	dBodySetMass(ball[$-1].b,&m1);
	dBodySetPosition(ball[$-1].b, 0,0,10);
	dGeomSetBody(ball[$-1].geom, ball[$-1].b);

	ball ~=
	* new obj(dBodyCreate(world), dCreateSphere(space, radius));
	dMassSetZero(&m1);
	dMassSetSphereTotal(&m1,mass,radius);
	dBodySetMass(ball[$-1].b,&m1);
	dBodySetPosition(ball[$-1].b, 0.2,0,7);
	dGeomSetBody(ball[$-1].geom, ball[$-1].b);

	foreach(i;0..300) simLoop();

	dWorldDestroy(world);
	dCloseODE();
}


当然,这个代码违反了不要拷贝的原则,不过我并不打算某部分整理成函数,  还是重新整理了一下,后面还会用到这里的代码

当然还是不够好,比如应该传入一个obj*来当做参数而不是position.


Mac-mini:ode$ cat example3.d
import std.stdio;
import ode;

static dWorldID world;
static dSpaceID space;
static dGeomID ground;
static dJointGroupID contactgroup;

const dReal radius = 0.2;
const dReal mass = 1.;

struct obj{
	dBodyID b;
	dGeomID geom;
	dReal radius, length, mass;
}

obj[] ball;

extern(System) void nearCallBack(void* date, dGeomID o1, dGeomID o2){
	const int N = 10;
	dContact[N] contact;
	int n = dCollide(o1,o2,N,&contact[0].geom,dContact.sizeof);
	for(int i=0;i<n;i++){
		with (contact[i].surface){
			mode = dContactBounce;
			mu = dInfinity;
			bounce = 0.;
			bounce_vel = 0.;
		}
		dJointID c = dJointCreateContact(world, contactgroup, &contact[i]);
		dJointAttach(c, dGeomGetBody(contact[i].geom.g1), dGeomGetBody(contact[i].geom.g2));
	}
}

void simLoop(){
	dSpaceCollide(space, null ,&nearCallBack);
	dWorldStep(world, 0.01);
	dJointGroupEmpty(contactgroup);
	dReal* pos;
	foreach(k,b;ball){
		pos = dBodyGetPosition(b.b);
		write("ball",k,"\t");
		foreach(i;0..3) writef("%.6f\t",*(pos+i));
	}
	writeln();
}

obj createsphere(float x, float y, float z){
	dMass m1;
	dMassSetZero(&m1);
	dMassSetSphereTotal(&m1,mass,radius);
	obj b = {b:dBodyCreate(world), geom: dCreateSphere(space,0.2), radius: 0.2, mass:1.};
	dBodySetMass(b.b,&m1);
	dBodySetPosition(b.b, x,y,z);
	dGeomSetBody(b.geom, b.b);
	return b;
}

void main(){
	dInitODE();
	world = dWorldCreate();
	space = dHashSpaceCreate(null);
	contactgroup = dJointGroupCreate(0);

	dWorldSetGravity(world, 0, 0, -9.8);
	ground = dCreatePlane(space, 0,0,1,0);

	ball ~= createsphere(0,0,10);
	ball ~= createsphere(0.1,0,6);

	foreach(i;0..300) simLoop();

	dWorldDestroy(world);
	dCloseODE();
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值