As I said in the subject, I have some problems in managing with collisions with the Sparky's ibrary.
Following the examples provided with the library I wrote a small application, but, unfortunately, I have two problems.
The first problem is that I can not handle properly the collision of an object, in fact, that, instead of following the terrain, flying through the map (as if he had not gravity). On the ground, however, do not collide, so collision run successfully.
Variables
float radius = 7.0f;
float littleRadius = 2.0f;
float gravity = -0.1f;
float slope = 0.5f;
int ground = 1;
int Oground = 1;
int jumptimer = 0;
float vx = 0;
float vy = 0;
float vz = 0;
float Ovx = 0;
float Ovy = 0;
float Ovz = 0;
This is the initialization of the terrain
void setupScene(void) {
dbLoadImage ( "texture.jpg", 1 ); // diffuse texture
dbLoadImage ( "detail.jpg", 2 ); // detail texture
// create the terrain
dbSetupTerrain ( ); // set up terrain library
dbMakeObjectTerrain ( 1 ); // make a new terrain
dbSetTerrainHeightMap ( 1, "map.bmp" ); // set the terrain height map
dbSetTerrainScale ( 1, 3, 0.6f, 3 ); // set the scale
dbSetTerrainSplit ( 1, 16 ); // set the split value
dbSetTerrainTiling ( 1, 4 ); // set the detail tiling
dbSetTerrainLight ( 1, 1.0f, -0.25f, 0.0f, 1, 1, 0.78f, 0.5f ); // set the light
dbSetTerrainTexture ( 1, 1, 2 ); // set the textures
dbBuildTerrain ( 1 ); // build the terrain
SC_SetupComplexObject( 1, 1, 2 );
}
This is the initialization of the object
void makeEnemies (int num) {
for(int i = 10; i < 10 + num; i++ ) {
dbMakeObjectSphere( i,littleRadius*2.0f );
dbPositionObject(i, 478, 20, 70 );
dbColorObject( i, dbRgb(255, 0, 0)) );
SC_SetupObject( i, 3, 1 );
SC_AllowObjectScaling( i );
}
}
This is the function that control the movement of the object (collisions and gravity)
void moveEnemies (int num) {
for( int i = 10; i < 10+num; i++ ) {
float oldx = dbObjectPositionX(i);
float oldy = dbObjectPositionY(i);
float oldz = dbObjectPositionZ(i);
//dbPointObject(i, dbObjectPositionX(2), dbObjectPositionY(2), dbObjectPositionZ(2) );
dbPointObject( i,dbCameraPositionX(),dbCameraPositionY(),dbCameraPositionZ() );
dbMoveObject(i, 0.2 );
Ovx = 0;
Ovz = 0;
float x = oldx + Ovx;
float y = oldy + Ovy;
float z = oldz + Ovz;
int collide = SC_SphereCastGroup( 0, oldx, oldy, oldz, oldx, oldy+Ovy, oldz, littleRadius, 0 );
if ( collide > 0 ) {
float ny = SC_GetCollisionNormalY();
if ( dbAbs(ny) > slope ) {
oldy = SC_GetStaticCollisionY();
}
else {
x = x - oldx;
z = z - oldz;
oldx = SC_GetCollisionSlideX();
oldy = SC_GetCollisionSlideY();
oldz = SC_GetCollisionSlideZ();
x = x + oldx;
z = z + oldz;
}
if ( ny > slope ) {
Oground = 1;
Ovy = 0;
}
else {
Oground = 0;
if ( ny < -slope ) {
Ovy = gravity;
}
}
}
else {
oldy = oldy + Ovy;
Oground = 0;
}
collide = SC_SphereSlideGroup(1, oldx, oldy, oldz, x, oldy, z, littleRadius, i );
if ( collide > 0 ) {
dbPositionObject(i, SC_GetCollisionSlideX(), SC_GetCollisionSlideY(), SC_GetCollisionSlideZ() );
}
SC_UpdateObject( i );
}
}
The second problem, however, relates to another object falling through the ground, so the collision is not done correctly.
This is the function that control the movement of the second object (character played by by human)
void movePG (void) {
//rotate player with mouse
dbYRotateObject( 2, dbObjectAngleY(2) + dbMouseMoveX()/3.0f );
dbXRotateObject( 2, dbObjectAngleX(2) + dbMouseMoveY()/3.0f );
float oldx = dbObjectPositionX(2);
float oldy = dbObjectPositionY(2);
float oldz = dbObjectPositionZ(2);
//apply gravity, and user changes to movement
float angy = dbObjectAngleY(2);
vx = 0;
vz = 0;
//if player is jumping or falling then apply 'normal' gravity
//if not attempt to keep the player stuck to the floor
if ( vy == 0 && jumptimer == 0 ) {
vy = vy + 10*gravity;
}
else {
vy = vy + gravity;
}
if (dbKeyState(32) == 1 ) {
vx = vx + dbCos(angy);
vz = vz - dbSin(angy);
}
if (dbKeyState(30) == 1 ) {
vx = vx - dbCos(angy);
vz = vz + dbSin(angy);
}
if (dbKeyState(31) == 1 ) {
vx = vx - dbSin(angy);
vz = vz - dbCos(angy);
}
if (dbKeyState(17) == 1 ) {
vx = vx + dbSin(angy);
vz = vz + dbCos(angy);
}
//only jump if on ground, and a certain time after last jump
if ( ground == 1 ) {
if ( dbSpaceKey() == 1 && jumptimer == 0 ) {
vy = vy + 3.0f;
jumptimer = 20;
}
}
//this would be the player's final position without collision
float x = oldx + vx;
float y = oldy + vy;
float z = oldz + vz;
int collide = SC_SphereCastGroup( 1, oldx, oldy, oldz, oldx, oldy+vy, oldz, radius, 0 );
if ( collide > 0 )
{
//how flat is this ground
float ny = SC_GetCollisionNormalY();
if ( dbAbs(ny) > slope ) {
//FLAT, stick
oldy = SC_GetStaticCollisionY();
}
else {
//STEEP, slide
x = x - oldx;
z = z - oldz;
oldx = SC_GetCollisionSlideX();
oldy = SC_GetCollisionSlideY();
oldz = SC_GetCollisionSlideZ();
x = x + oldx;
z = z + oldz;
}
//ny#<0 means the player has hit a ceiling rather than a floor
if ( ny > slope ) {
//only on ground if standing on flat ground
ground = 1;
vy = 0;
}
else {
ground = 0;
//if player has hit a flat ceiling then stop vy# movement
if ( ny < -slope ) {
vy = gravity;
}
}
}
else {
//nothing below player, not on ground, add vertical speed to player
oldy = oldy + vy;
ground = 0;
}
//jumptimer will decrease only when player is back on ground
//creates a pause between two successive jumps
if ( ground == 1 && jumptimer > 0 ) {
jumptimer--;
}
//handle horizontal movement as sliding
//player only collides with group 1 (level) objs and moves freely through others
collide = SC_SphereSlideGroup( 1, oldx, oldy, oldz, x, oldy, z, radius, 0 );
if ( collide > 0 ) {
//if hit, reposition player, halt movement vector
x = SC_GetCollisionSlideX();
oldy = SC_GetCollisionSlideY();
z = SC_GetCollisionSlideZ();
vx = 0;
vz = 0;
//possible code for giving the player a jumping help up stairs...
//might be useful if slope# is set very high but stairs are still required
//dy = oldy - SC_GetStaticCollisionY()
//if ( dy < slope && dy > 0 && ground == 1 ) vy = 0.5;
}
//position the player
dbPositionObject( 2, x, oldy, z );
SC_UpdateObject(2);
}
Have you have any idea?
I simply took the source code of examples and adapted it to my little scenario.
In attachment I uploaded binaries of the two cases.
Thanks in advance for you replys (and sorry my bad english).