Raydium 3D Game Engine

Official forum for everything about Raydium, ManiaDrive, MeMak, ...
It is currently Tue Mar 19, 2024 2:36 am

All times are UTC




Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: antigravity gun
PostPosted: Sun Feb 10, 2008 12:16 pm 
Offline
User avatar

Joined: Thu Sep 29, 2005 2:59 pm
Posts: 828
Well, here is an ugly and bad first step to achieve an antigravity-gun.
The code is mainly copy/paste of other examples so maybe is not too clear right now.

Anyway i have noticed a big problem.
When we attach 2 objects we really are attaching 2 elements, so we create a new big object. That behaviour doesn't looks like the regular one in FPS games.
In half life2, for example, you can grab a box, move to a small door and you will pass but the box won't (and eventually the joint will break).
I think this can not be done with the current system of joints.
Am i wrong?

GIF with a graphical explanation of the problem.
Image
And here the code:
Code:
/*
    Raydium - CQFD Corp.
    http://raydium.org/
    License: GPL - GNU General Public License, see "gpl.txt" file.
*/

/* This howto attemp to show how to create a gravity-like-gun
    It's importat to read how_to_point_an_object.c
   By one side we are putting here the most code of how_to_point_an_object.c  and a bit of test6.c
   From tes6 we are going to put a moveable character.
   From how_to_point_an_object.c we are creating a pair of objects and the code for pointing.
   Also we will take account of rrp_play.c for the code to link an object to another on the fly.
*/
   
#include "raydium/index.c"

int object1, object2; /*variables for the 2 objects used in the demo*/
int a; /* main character */
dReal cam_angle_h=0;
dReal cam_angle_v=90;
#define DEFAULT_RAND_DEC raydium_random_f(-3,3)
#define DEFAULT_DEC DEFAULT_RAND_DEC,DEFAULT_RAND_DEC,0
int debug=1;

//attaching variables. This could be done by an external function
signed char attached=0; // is camera attached to something ?
int attached_id; // if yes, which element is it ?
dReal attached_pos[3]; // and where the camera is ? (relative to this element)
dReal attached_lookat[3]; // and what are we looking at ? (relative, too)

/*function to create a pair of objects in the scene, near 0,0,0*/
void create_objects(void)
{
   object1=raydium_ode_object_find("OBJ1");
    object1=raydium_ode_object_create ("OBJ1");
    raydium_ode_object_box_add("element1",object1,0.1,RAYDIUM_ODE_AUTODETECT,0,0,RAYDIUM_ODE_STANDARD,0,"crate.tri");
     /*Fix to prevent quite sligth movements betwen objects caused by a non-enough friction force*/
   /*Usually this won't be necesary, but usefull in the case you are showing numeric values*/
    raydium_ode_element_slip_name("element1",0);
   
    object2=raydium_ode_object_find("OBJ2");
    object2=raydium_ode_object_create ("OBJ2");
    raydium_ode_object_box_add("element2",object2,0.3,RAYDIUM_ODE_AUTODETECT,0,0,RAYDIUM_ODE_STANDARD,0,"crate.tri");
    raydium_ode_object_move_3f (object2,2,0,0);
    /*Fix to prevent quite sligth movements betwen objects caused by a non-enough friction force*/
   /*Usually this won't be necesary, but usefull in the case you are showing numeric values*/
    raydium_ode_element_slip_name("element2",0);   
}
/*function to create our character.
 As it is a FPS main character it will use a particular subset of funtions focussed to FPS
 */
void create_character(void){

   
      // float reload_time=RELOAD_TIME;
   
    raydium_ode_object_delete_name("PLAYER");
    a=raydium_ode_object_create("PLAYER");
    raydium_ode_object_sphere_add("player",a,1,RAYDIUM_ODE_AUTODETECT,RAYDIUM_ODE_STANDARD,0,"lego.tri");
    raydium_ode_element_material_name("player",RAYDIUM_ODE_MATERIAL_SOFT2);
    raydium_ode_element_player_set_name("player",1);
    raydium_ode_motor_create("player_react",a,RAYDIUM_ODE_MOTOR_ROCKET);
    raydium_ode_motor_rocket_set_name("player_react","player",0,0,0);
    raydium_ode_motor_rocket_playermovement_name("player_react",1);
    raydium_ode_element_slip_name("ground",RAYDIUM_ODE_SLIP_ICE/2.f);
   //raydium_ode_element_OnBlow_name("player",blow_touched);
       raydium_ode_element_move_name_3f("player",3,3,1);
   #define DEFAULT_RAND_DEC raydium_random_f(-3,3)
   #define DEFAULT_DEC DEFAULT_RAND_DEC,DEFAULT_RAND_DEC,0
   //raydium_ode_object_move_name_3f("BUGGY", DEFAULT_DEC);
   raydium_ode_object_move_name_3f("PLAYER",DEFAULT_DEC);
    //raydium_ode_object_move_name_3f("PLAYER",2,0,0);

}

/* usual callback funtion "display" */
void display(void)
{
   /*3 variables for the pointing */
   dReal pos[3];   /*position of the pointed point */
   dReal dist;      /*distance of the pointed point from de point of view*/
   dReal weapon_range;
   int id_pointed; /*id of the pointed object */
   weapon_range=101;
   
   raydium_joy_key_emul();

   if(raydium_key_last==1027)
      exit(0);
   if(raydium_key_last==1000+'d')debug=debug?0:1;
      
   /* code to move the player */
   int dir=5;
   float speed=0.2;
   float ptmp=0;

   // directions indices:
   // 1    2    3
   //      ^
   // 4 <- 5 -> 6
   //      v
   // 7    8    9

   if(raydium_key[GLUT_KEY_LEFT])  dir=4;
   if(raydium_key[GLUT_KEY_RIGHT]) dir=6;
   if(raydium_key[GLUT_KEY_UP]) dir=2;
   if(raydium_key[GLUT_KEY_DOWN]) dir=8;

   if(raydium_key[GLUT_KEY_LEFT] && raydium_key[GLUT_KEY_UP]) dir=1;
   if(raydium_key[GLUT_KEY_RIGHT] && raydium_key[GLUT_KEY_UP]) dir=3;

   if(raydium_key[GLUT_KEY_LEFT] && raydium_key[GLUT_KEY_DOWN]) dir=7;
   if(raydium_key[GLUT_KEY_RIGHT] && raydium_key[GLUT_KEY_DOWN]) dir=9;

   switch(dir)
      {
      case 1:
      ptmp=-45;
      break;
      case 2:
      ptmp=0;
      break;
      case 3:
      ptmp=45;
      break;
      case 4:
      ptmp=-90;
      break;
      case 5:
      speed=0; // stops player
      break;
      case 6:
      ptmp=90;
      break;
      case 7:
      ptmp=-135;
      break;
      case 8:
      ptmp=180;
      break;
      case 9:
      ptmp=135;
      break;
      }

   raydium_ode_motor_speed_name("player_react",speed);
   raydium_ode_motor_rocket_orientation_name("player_react",0,90,ptmp);
   
   /*Till here the code to move the player */
      
   /*checking the id of the object pointed, at a maximum of 101 units of distance */
   id_pointed = raydium_ode_mouse_pick(weapon_range,pos,&dist);      

   
   
   
    raydium_osd_printf((100.0f*raydium_mouse_x)/raydium_window_tx,100-(100.0f*raydium_mouse_y)/raydium_window_ty,16,0.5,"font2.tga","+ %d %.3f %.3f %.3f %.3f",id_pointed,pos[0],pos[1],pos[2],dist);
    if (raydium_mouse_button[0] && id_pointed>0 ){
        if (raydium_ode_element[id_pointed].state == RAYDIUM_ODE_STANDARD){
            pos[1]=pos[0]=0;
            pos[2]=5;
            //raydium_ode_element_addforce(id_pointed,pos);
            //now the object has to be linked to the character
             if(!attached)
         {
            raydium_log("Linking the object to the character");
            int id;
            dReal pos[3];
            dReal cam[3];
            dReal dist;
            
            id = raydium_ode_mouse_pick(100,pos,&dist);
            
            if(id>=0)
            {
               // attached_pos (camera pos to element's space)
               cam[0]=raydium_camera_x;
               cam[1]=raydium_camera_y;
               cam[2]=raydium_camera_z;
               raydium_ode_element_world2rel(id,cam,attached_pos);
               // attached_lookat (impact pos to element's space)
               raydium_ode_element_world2rel(id,pos,attached_lookat);
               attached_id=id;
               attached=1;
               raydium_ode_joint_attach_hinge("hang_joint",3,id_pointed,cam[0],cam[1],cam[2],RAYDIUM_ODE_JOINT_AXE_X);
            }   
         }
         else // is alread attached
         {
            //raydium_ode_joint_break_name("hang_joint");
            raydium_ode_joint_delete_name("hang_joint");
            attached=0;
         }   
      }
   }
   
   
   raydium_clear_frame();
   /* [ place your camera here ] */
   /*raydium_camera_look_at(10,-2,2,0,0,0);*/
   
   
   
   
   float sensivity=1;
   float delta_x;
   float delta_y;
   float zoomfact=1;
   zoomfact=raydium_projection_fov/70;
   delta_x = (raydium_mouse_x - (raydium_window_tx/2.f))*sensivity*zoomfact;
   delta_y = (raydium_mouse_y - (raydium_window_ty/2.f))*sensivity*zoomfact;
   cam_angle_h += (delta_x*0.008f); // rads
   
   cam_angle_v += (delta_y*0.458f); // degs
   raydium_mouse_move(raydium_window_tx/2, raydium_window_ty/2);
   raydium_ode_element_player_angle_name("player",cam_angle_h);
   if(cam_angle_v<1) cam_angle_v=1;
   if(cam_angle_v>179) cam_angle_v=179;
   raydium_ode_element_camera_inboard_name("player",-0.3,-0.3,0.25, raydium_trigo_sin(cam_angle_v),0,raydium_trigo_cos(cam_angle_v));
   
   /* [ draw here ] */
   raydium_ode_draw_all(RAYDIUM_ODE_DRAW_NORMAL);
   raydium_ode_draw_all(RAYDIUM_ODE_DRAW_RAY);
   if(debug)
   {
       raydium_ode_draw_all(RAYDIUM_ODE_DRAW_DEBUG);
       raydium_ode_draw_all(RAYDIUM_ODE_DRAW_AABB);
    }
   
   /* we put the info on the screen each frame */
   raydium_osd_printf(2,98,18,0.5,"font2.tga","HOW TO antigravity-gun",id_pointed);
   raydium_osd_printf(2,95,18,0.5,"font2.tga","Id of object:%d",id_pointed);
   raydium_osd_printf(2,92,18,0.5,"font2.tga","Position of the pointed point: (%f, %f, %f)",pos[0],pos[1],pos[2]);
   raydium_osd_printf(2,89,18,0.5,"font2.tga","Distance to the pointed point: %f (raydium)units.",dist);
   raydium_osd_printf(2,86,18,0.5,"font2.tga","Press d to toogle debug drawing.");
   raydium_osd_printf(2,83,18,0.5,"font2.tga","Click on a box to grab it. Click again to release it. It's a bit tricky.");
   

   raydium_rendering_finish();
}


int main(int argc, char **argv)
{
   raydium_init_args(argc,argv);
   raydium_window_create(640,480,RAYDIUM_RENDERING_WINDOW,"My app");

   raydium_texture_filter_change(RAYDIUM_TEXTURE_FILTER_TRILINEAR);
   raydium_window_view_perspective(60,0.01,2500); // fov 60 + near and far planes

   raydium_fog_disable();   
   raydium_light_enable();
   raydium_light_on(0);

   raydium_light_conf_7f(0,50,150,200,1000000,1,0.9,0.7); // id, pos, intensity and color (RGB)
   raydium_background_color_change(1,0.9,0.7,1);

   raydium_sky_box_cache();

   /* [ place base scene here ] */ raydium_ode_ground_set_name("cocorobix.tri");
      
   /* create a pair of objects to have something to point to */
   create_objects();
   create_character();

   /*forcing the render of a cursor in the mouse position*/
   raydium_osd_cursor_set("BOXcursor.tga",4,4);
      
   raydium_callback(&display);
   return(0);
}

// EOF


Top
 Profile  
 
 Post subject:
PostPosted: Sun Feb 10, 2008 12:31 pm 
Offline
User avatar

Joined: Thu Sep 29, 2005 2:59 pm
Posts: 828
autoresponse: yes, i'm wrong. I did the test quite bad.

Well, and now:
1.- Ideas to minimize the effect of the mass of the grabbed object in the player forces? I mean in the games the player is not affeted by the mass of the object. However i have to admit that i like a gravity gun that could affect a bit in the forces over the player.
2.- How to move up/down the object with the mouse?
3.- Is it possible to vary (in realtime) the distance of a joint? I want use mouse4 mouse5 to move closer/further the grabbed object.
4.- With a wii/ps3 pad we could add a 2 axes rotation feature to place the object exactly as we want.


Top
 Profile  
 
 Post subject: Gravity gun
PostPosted: Sun Feb 10, 2008 10:28 pm 
Offline

Joined: Sun Oct 09, 2005 10:46 pm
Posts: 759
Hello,

I think that gravity don't rely on join but only on force.

When in attract mode: a force computed from object to a point in front of player is applied to object. Object come near player.
The point is function of player point of view. Like this object will follow the mouse.
This force is sclaed down by the distance from object to target point.

My first attempt to add gravity gun like this work quite well.
But there are lot's of tunning parameter to adjust.

Try like this. If i have some time i'll try to work on my old prog (but i don't know where is it).

For now i try to understand opengl camera placement and frustrum and thing like this.

Have a nice day.
Ouille.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 12, 2008 1:20 am 
Offline
User avatar

Joined: Thu Sep 29, 2005 2:59 pm
Posts: 828
Hmmm.... ok that sounds fine.

So we can use forces to get the antigravity gun and the joints for grabbing a near object.
If you could paste here your previous code you'll save a lot of my time :)


Top
 Profile  
 
 Post subject: hello
PostPosted: Tue Feb 12, 2008 2:22 pm 
Offline

Joined: Sun Oct 09, 2005 10:46 pm
Posts: 759
Here is a sample code just modifying a bit your own:

Code:
    // When not attached
    if (attached==0){// No object attached
        if (raydium_mouse_button[0] && id_pointed>0)
            if (raydium_ode_element[id_pointed].state == RAYDIUM_ODE_STANDARD){
                attached=1; // Now attached
                attached_id=id_pointed;
            }
    }
    // If attached and mouse button released
    if (attached==1 || attached==3){ //Object attached gravity enabled
        if (!raydium_mouse_button[0]){ //Handle mode
            attached++; // Enter "hold mode" 2 ou 0
            if (attached==4)
                attached=0;
        }
       
    }
    // If attraction enabled
    if (attached==1 || attached==2){ // Atractive force
        dReal * opos,* ppos,rf[3];
        dReal rpos[3];
        dReal rot[3];
        dReal dist;
        opos=raydium_ode_element_pos_get(attached_id);
       
        ppos=raydium_ode_element_pos_get_name("player");
        raydium_ode_element_rot_get_name("player",&rot[0],&rot[1],&rot[2]);
       
        rpos[0]=cos(rot[2]); // object target in front of player
        rpos[1]=sin(rot[2]);
        rf[0]=ppos[0]-opos[0]+rpos[0]; // Vector from object to 1 unti in front of player
        rf[1]=ppos[1]-opos[1]+rpos[1];
        rf[2]=ppos[2]-opos[2]+0.2;
        dist=sqrt(rf[0]*rf[0]+rf[1]*rf[1]+rf[2]*rf[2]); // Normalisation
       
        rf[2]/=dist;
       // if (dist<1)
       //     dist=100;
        rf[0]/=dist;
        rf[1]/=dist;
        // Missing raydium_ode_element_linearvelocity_set ...
        dBodySetLinearVel(raydium_ode_element[attached_id].body,rf[0],rf[1],rf[2]); // Can use addforce but need to damp else it's an oscillator
    }
    if (attached==2){
        if (raydium_mouse_button[0]){
            //throwing object
        dReal * opos,* ppos,rf[3];

        opos=raydium_ode_element_pos_get(attached_id);
       
        ppos=raydium_ode_element_pos_get_name("player");
       

        rf[0]=opos[0]-ppos[0];
        rf[1]=opos[1]-ppos[1];
        rf[2]=opos[2]-ppos[2];
        rf[0]*=100;
        rf[1]*=100;
        rf[2]*=100;
        raydium_ode_element_addforce(attached_id,rf);
            attached=3;
            attached_id=-1;
        }
    }


target is line 159 in display function.
I can post all the code if you want.
test it.

Have a nice day.
Ouille


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 14, 2008 9:35 am 
Offline
User avatar

Joined: Thu Sep 29, 2005 2:59 pm
Posts: 828
Thanks, it worked.
Now, i'm tunning it a bit and adding a few features and as soon as it will be finished i'll paste here the new code.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 6 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group