Hey, I'm trying to port some of my DBP code to DGDK, and it's not working in the same way. It's a basic physics lib that has the exact same code in DGDK as in DBP (using some of C++'s features to cut it down a bit), but it doesn't work. The parameters I use to test it are all identical.
The problem is that in the DBP version the ball moves around nice and smooth, but in the DGDK one it's very jerky. I've tried making more levels for testing, but to no avail.
Here is the DBP code:
kxbody(body).frcw.x=0
kxbody(body).frcw.y=kxbody(body).mass*kxworlddata.grav
kxbody(body).frcw.z=0
kxbody(body).frcd.x=-(((kxbody(body).dragc+(kxmat(kxbody(body).mat).fric*kxbody(body).ccoll))/2)*kxbody(body).size*kxworlddata.dens*((kxbody(body).vel.x^2)*sgn(kxbody(body).vel.x)))
kxbody(body).frcd.y=-(((kxbody(body).dragc+(kxmat(kxbody(body).mat).fric*kxbody(body).ccoll))/2)*kxbody(body).size*kxworlddata.dens*((kxbody(body).vel.y^2)*sgn(kxbody(body).vel.y)))
kxbody(body).frcd.z=-(((kxbody(body).dragc+(kxmat(kxbody(body).mat).fric*kxbody(body).ccoll))/2)*kxbody(body).size*kxworlddata.dens*((kxbody(body).vel.z^2)*sgn(kxbody(body).vel.z)))
kxbody(body).frc.x=kxbody(body).frct.x+kxbody(body).frcw.x+kxbody(body).frcd.x+kxbody(body).frcc.x+kxbody(body).frcs.x
kxbody(body).frc.y=kxbody(body).frct.y+(kxbody(body).frcw.y*(1-kxbody(body).ccoll))+kxbody(body).frcd.y+kxbody(body).frcc.y+kxbody(body).frcs.y
kxbody(body).frc.z=kxbody(body).frct.z+kxbody(body).frcw.z+kxbody(body).frcd.z+kxbody(body).frcc.z+kxbody(body).frcs.z
kxbody(body).acc.x=kxbody(body).frc.x/kxbody(body).mass
kxbody(body).acc.y=kxbody(body).frc.y/kxbody(body).mass
kxbody(body).acc.z=kxbody(body).frc.z/kxbody(body).mass
kxbody(body).vel.x=kxbody(body).vel.x+kxbody(body).acc.x
kxbody(body).vel.y=kxbody(body).vel.y+kxbody(body).acc.y
kxbody(body).vel.z=kxbody(body).vel.z+kxbody(body).acc.z
if (kxbody(body).ccoll)
kxbody(body).vel.x = kxbody(body).vel.x * kxmat(kxbody(body).mat).fric
kxbody(body).vel.y = kxbody(body).vel.y * kxmat(kxbody(body).mat).fric
kxbody(body).vel.z = kxbody(body).vel.z * kxmat(kxbody(body).mat).fric
endif
kxbody(body).speed=sqrt(kxbody(body).vel.x^2+kxbody(body).vel.y^2+kxbody(body).vel.z^2)
kxbody(body).pos.x=kxbody(body).pos.x+kxbody(body).vel.x
kxbody(body).pos.y=kxbody(body).pos.y+kxbody(body).vel.y
kxbody(body).pos.z=kxbody(body).pos.z+kxbody(body).vel.z
if kxbody(body).mode=1
c=sc_sphereSlide(0,kxbody(body).pos.x-kxbody(body).vel.x,kxbody(body).pos.y-kxbody(body).vel.y,kxbody(body).pos.z-kxbody(body).vel.z,kxbody(body).pos.x,kxbody(body).pos.y,kxbody(body).pos.z,kxbody(body).size,kxbody(body).cobj)
if c>0
kxbody(body).cldd=c
kxbody(body).ccoll=1
else
kxbody(body).ccoll=0
kxbody(body).cldd=0
endif
if kxbody(body).ccoll=1
kxbody(body).pos.x=sc_getCollisionSlideX()
kxbody(body).pos.y=sc_getCollisionSlideY()
kxbody(body).pos.z=sc_getCollisionSlideZ()
kxbody(body).frcs.x=-(sc_getCollisionNormalX()*kxbody(body).frcw.y)
kxbody(body).frcs.y=-(sc_getCollisionNormalY()*kxbody(body).frcw.y)
kxbody(body).frcs.z=-(sc_getCollisionNormalZ()*kxbody(body).frcw.y)
kxbody(body).frcc.x=(sc_getCollisionNormalX()*kxbody(body).frc.x)
kxbody(body).frcc.y=(sc_getCollisionNormalY()*kxbody(body).frc.y)
kxbody(body).frcc.z=(sc_getCollisionNormalZ()*kxbody(body).frc.z)
else
kxbody(body).frcs.x=kxbody(body).frcs.x*0
kxbody(body).frcs.y=kxbody(body).frcs.y*0
kxbody(body).frcs.z=kxbody(body).frcs.z*0
kxbody(body).frcc.x=kxbody(body).frcc.x*0
kxbody(body).frcc.y=kxbody(body).frcc.y*0
kxbody(body).frcc.z=kxbody(body).frcc.z*0
endif
endif
position object kxbody(body).obj,kxbody(body).pos.x,kxbody(body).pos.y,kxbody(body).pos.z
sc_updateObject kxbody(body).obj
And the DGDK code (it doesn't use the same arrays are stuff, but the data all matches up in the end):
// Calculate weight force
_frce[1].Set( 0.0f, _mass * WorldData.first, 0.0f );
// Calculate drag force
_frce[2].Set( - ( ( ( _dragc + ( _collided ? _fric : 0 ) ) / 2.0f ) * _size * WorldData.second * ( ( _vel.X() * _vel.X() ) * ( _vel.X() >=0 ? 1 : -1 ) ) ),
- ( ( ( _dragc + ( _collided ? _fric : 0 ) ) / 2.0f ) * _size * WorldData.second * ( ( _vel.Y() * _vel.Y() ) * ( _vel.Y() >=0 ? 1 : -1 ) ) ),
- ( ( ( _dragc + ( _collided ? _fric : 0 ) ) / 2.0f ) * _size * WorldData.second * ( ( _vel.Z() * _vel.Z() ) * ( _vel.Z() >=0 ? 1 : -1 ) ) )
);
// Calculate total force
_frc = _frce[0].Add( OOGDK::Vector( _frce[1].X(), _collided ? 0.0f : _frce[1].Y(), _frce[1].Z() ).Add( _frce[2].Add( _frce[3].Add( _frce[4] ) ) ) );
// Calculate acceleration, velocity and position
_acc = _frc.Divide( _mass );
_vel = _vel.Add( _acc );
if ( _collided ) _vel.Multiply( _fric );
_pos = _pos.Add( _vel );
// Not static
if ( !_static )
{
DWORD ColObj = SC_SphereSlide( 0, _pos.X() - _vel.X(), _pos.Y() - _vel.Y(), _pos.Z() - _vel.Z(), _pos.X(), _pos.Y(), _pos.Z(), _size, _obj.GetID() );
if ( ColObj > 0 )
{
_collided = true;
_pos.Set( SC_GetCollisionSlideX(), SC_GetCollisionSlideY(), SC_GetCollisionSlideZ() );
_frce[3].Set( -( SC_GetCollisionNormalX() * _frce[1].Y() ), -( SC_GetCollisionNormalY() * _frce[1].Y() ), -( SC_GetCollisionNormalZ() * _frce[1].Y() ) );
_frce[4].Set( SC_GetCollisionNormalX() * _frc.X(), SC_GetCollisionNormalY() * _frc.Y(), SC_GetCollisionNormalZ() * _frc.Z() );
}
else
{
_collided = false;
_frce[3] = OOGDK::Vector();
_frce[4] = OOGDK::Vector();
}
}
// Update object
_obj.Position( _pos );
SC_UpdateObject( _obj.GetID() );
The basic order of things is (in both sources):
- Calculate weight force
- Calculate drag force
- Add all forces together (in the C++ version I use a vector class for this. I've tested it over and over and it doesn't have any problems)
- Get the acceleration from the force, get the velocity from the acceleration, apply friction on collision (tested this too, not the problem), and then get new positions
- Collision: If there is a collision (using Sparky's SphereSlide function), then position object at sliding positions, and handle the collision and sliding force
- Position and update the object
Obviously the jerking would occur in positioning the object. As you can see in the code, I only position the object once, but I set the position coordinates in two seperate parts. The first part is where I add on the velocity, and the second where I assign the sliding positions (from Sparky's plugin). Obviously when adding on values to gradually affect the position it would not give any jerking (and tbh, I don't see any problem there with the velocity code). It only jerks on collisions, and the only other place where I position the object is on the collision, so that must be the root of the problem. Either I have been really stupid and made a big mistake, or it's a problem with Sparky's collision functions.
I've revised the code over and over and this is the only problem I can find. I guess this naturally leads to this question too: Are there perhaps any really easy and basic physics libs out there that I could use? I only need it for spheres really.
Thanks
Don't you just hate that Zotoaster guy?