Raydium 3D Game Engine

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

All times are UTC




Post new topic Reply to topic  [ 29 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Portals System
PostPosted: Wed Nov 07, 2007 12:35 am 
Offline
User avatar

Joined: Thu Sep 29, 2005 2:59 pm
Posts: 828
Thread to discuss about Portals system.
Here a video about the game Portal (from Valve) that make use of that system:
http://download.gametrailers.com/gt_vault/t_halflife2ob_e32k7_portal_wt_gt_h264.mov

last update:
7-nov-2007

Idea:
The portals are like gates that can be placed dynamically in different places and allow characters and objects to pass through it in both directions.
As portals can be placed in different planes a vertical portal can be linked to a horizontal portal in the roof, so if you pass through the vertical one walking, you suddenly be falling from the roof. The previous video shown this clearer.

Goals:
We are not trying to clone the Valve implementation of Portals, mainly cause personally i think it's not as good as it should be :roll:
Raydium should be able to create portals easily, also every (with some limits) object in the game could pass through those portals, characters included.
Volumetric portals, like boxes or spheres could be added also.

Media:
Right now i have prepared a box, equivalent to the used in the game Portal.
http://vicentecarro.dyndns.org/raydium/portal-box.tar.bz2

Focus
Since this tasks is a bit hard, is not too much clever to implement it directly without a good plan.
Here my modest view of the problem:
When the gun shoots to a valid wall then we can create a rectangle in the wall. That rectangle would be one face of a influence box.
If one object enters the influence box then a replicate one would be created near the other portal but in the inverse of the depth(in other words, in the other side of the portal).
Portal(of Valve), surely, is using another approach. Looks like the physic mesh is splited when is touching the portal plane. Each part of this splitting would be placed in each one of the portals. But this is not acurate and make things difficult to manage objects not "prepared for portal".

About he rendering of the portals i see two possible methods:
One way is the old one. It means render what a portal should view, convertit into a textura and then texturize the other portal with that texture.
The other way could be based in sequenced renders. First we render what the other portal should view and then we render the character cam, over the previous graphic memory, but the portal texture would be transparent, to let see through it the other portal content. More pre-renders could be possible to improve the visual quality of recursive viewings.

Comments please.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Nov 11, 2007 11:14 pm 
Offline
User avatar

Joined: Sun Mar 16, 2003 2:53 am
Posts: 2591
Location: gnniiiii (Scrat)
Nice idea, and Portal seems to be quiet a success.

About portals physics, the big problem IMHO is that we should be able to show a ODE element twice (entering to 1st portal and exiting the 2nd at the same time). Without this visual effect, we only have to move a element when it touches an invisible ODE box (like ManiaDrive boosts, for instance) to another place (the "destination" portal). I haven't played Portal yet, so I may have said stupid things so far :)

Rendering portals is quiet complex too, because of the parallax. I've the same trouble for ManiaDrive 2 mirrors ;)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 12, 2007 1:17 am 
Offline
User avatar

Joined: Thu Sep 29, 2005 2:59 pm
Posts: 828
Boolean operations can be done with collision meshes in ODE? intersection, remove, etc...

Btw, maniadrive 2 mirrors!? Looks like a new thread :)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 12, 2007 5:15 pm 
Offline
User avatar

Joined: Sun Mar 16, 2003 2:53 am
Posts: 2591
Location: gnniiiii (Scrat)
No, ODE only deals with collision detection and physics. But it's easy to (visually) cut any mesh with a "phantom texture" : rgb(-1,-1,-1), like the ground in the augmented reality demo. Do we need that ?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 12, 2007 5:23 pm 
Offline

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

Looking at portal raise some problems:

View for the portal is a dynamic texture, computed from the same scene.
erhaps the viewport feature of test8 can help ?

Object teleportation is perhaps more difficult:
Need to destroy and re create object for on poit of the portal to the other one, but the bidirectonnal way can cause problem.

Third level design need to be very accurate, else some portal will be inconsistensy.

We can try ...
Ouille


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 13, 2007 12:41 am 
Offline
User avatar

Joined: Thu Sep 29, 2005 2:59 pm
Posts: 828
third level design?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 13, 2007 7:55 pm 
Offline

Joined: Sun Oct 09, 2005 10:46 pm
Posts: 759
Oups for level design.

Portal don't go forward wall, but from one wall to an other.

Sorry :o(

Ouille


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 13, 2007 10:46 pm 
Offline
User avatar

Joined: Thu Sep 29, 2005 2:59 pm
Posts: 828
maybe i'm a bit "hard" these days, but i don't get you


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 15, 2007 12:44 pm 
Offline
User avatar

Joined: Sun Mar 16, 2003 2:53 am
Posts: 2591
Location: gnniiiii (Scrat)
"Third level design need to be very accurate" becomes "The level design need to be very accurate", I think. Nothing more :)

It's a proof that portals are complex things: we get lost for anything than one word ;)


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 15, 2007 1:19 pm 
Offline
User avatar

Joined: Thu Sep 29, 2005 2:59 pm
Posts: 828
Ok , understood :)

Returning to the matter:
I think we can start creating a pair of cubes.
When you enter the blue one a linked copy of "you" will appear in the second one.
That should be enough easy and a good point to start.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 15, 2007 5:27 pm 
Offline

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

You're right Xfennec.

Normaly i want to expose 3 points.

Portal physic scare me !

If you have a model and a sample program i'll try to make objects going from one portal to the other one.


Have a nice day
Ouille.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 15, 2007 6:05 pm 
Offline
User avatar

Joined: Thu Sep 29, 2005 2:59 pm
Posts: 828
I'll post them tonight (maybe a bit late)


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 16, 2007 11:34 am 
Offline
User avatar

Joined: Thu Sep 29, 2005 2:59 pm
Posts: 828
it's taking a bit more than i expected. Patience ;)


Top
 Profile  
 
 Post subject:
PostPosted: Sat Nov 17, 2007 8:51 pm 
Offline
User avatar

Joined: Thu Sep 29, 2005 2:59 pm
Posts: 828
Ok, here the skeleton of the portal test.
It does NOT make duplication/teletransportation and so. It's just the basis.

You can toogle debug drawing with D(shift d)
You can move the camera with mouse and cursors
You can move the testing portalbox with a,w,s,d keys

http://vicentecarro.dyndns.org/raydium/test-portal.tar.bz2


Top
 Profile  
 
 Post subject:
PostPosted: Sat Nov 17, 2007 11:36 pm 
Offline
User avatar

Joined: Thu Sep 29, 2005 2:59 pm
Posts: 828
And now a first ugly test with a useless teletransport system:

Code:
/*
    Raydium - CQFD Corp.
    http://raydium.org/
    License: GPL - GNU General Public License, see "gpl.txt" file.
*/

// This file is a default skeleton. Replace all [ ... ] sections with yours.
// Have fun !

#include "raydium/index.c"

#define TYPE_PORTAL1 100
#define TYPE_PORTAL2 101
#define TYPE_BOX 102

int portal1, portal2;
int ball;
int portalbox;
int debug=1;
int bodycam;
float pb_x=0.5f;
float pb_y=0.0f;
float pb_z=0.3f;
int in_red=0;
int in_blue=0;
int teletransporting=0;

void teletransport1()
{
    if(!teletransporting)
    {
    teletransporting=1;
    //get delta from box to portal1
    dReal prev;
   
    prev=pb_x;
   
    raydium_log("Prev position %f, %f, %f",pb_x,pb_y,pb_z);
   
    raydium_log("starting teletransport");
   
    dReal *p1,*p2,d[3];
   
    p1=raydium_ode_element_pos_get_name("portal1");
    raydium_log("Portal 1: %f,%f,%f",p1[0],p1[1],p1[2]);
    p2=raydium_ode_element_pos_get_name("portal2");
    raydium_log("Portal 2: %f,%f,%f",p2[0],p2[1],p2[2]);
   
    d[0]=p2[0]-p1[0];
    d[1]=p2[1]-p1[1];
    d[2]=p2[2]-p1[2];
   
    //raydium_ode_element_move_name_3f("portalbox",d[0],d[1],d[2]);
    //raydium_ode_object_move_3f(portal1,d[0],d[1],d[2]);
   
    pb_x+=d[0];
    pb_y+=d[1];
    pb_z+=d[2];
   
    raydium_log("Teletransported");
    raydium_log("New situation: %f, %f, %f",pb_x,pb_y,pb_z);
    }   
}
void teletransport2()
{
    if(!teletransporting)
    {
    teletransporting=1;
    //get delta from box to portal1
    dReal prev;
   
    prev=pb_x;
   
    raydium_log("Prev position %f, %f, %f",pb_x,pb_y,pb_z);
   
    raydium_log("starting teletransport");
   
    dReal *p1,*p2,d[3];
   
    p1=raydium_ode_element_pos_get_name("portal2");
    raydium_log("Portal 1: %f,%f,%f",p1[0],p1[1],p1[2]);
    p2=raydium_ode_element_pos_get_name("portal1");
    raydium_log("Portal 2: %f,%f,%f",p2[0],p2[1],p2[2]);
   
    d[0]=p2[0]-p1[0];
    d[1]=p2[1]-p1[1];
    d[2]=p2[2]-p1[2];
   
    //raydium_ode_element_move_name_3f("portalbox",d[0],d[1],d[2]);
    //raydium_ode_object_move_3f(portal1,d[0],d[1],d[2]);
   
    pb_x+=d[0];
    pb_y+=d[1];
    pb_z+=d[2];
   
    raydium_log("Teletransported");
    raydium_log("New situation: %f, %f, %f",pb_x,pb_y,pb_z);
    }   
}

char collide(int e1, int e2, dContact *c)
{
int i1,i2;
i1=raydium_ode_element_tag_get(e1);
i2=raydium_ode_element_tag_get(e2);
if((i1==TYPE_BOX && i2==TYPE_PORTAL1)||(i1==TYPE_PORTAL1 && i2==TYPE_BOX))
    {
        raydium_log("Box Inside the Portal 1");
        in_red=1;
        return 0;
    }
if((e1==portalbox && e2==portal1) || (e1==portal1 && e2==portalbox))
{
    raydium_log("ALT:Box Inside the Portal 1");
        in_red=1;
        return 0;
}
/*
if(i1==TYPE_BALANCIER || i2==TYPE_BALANCIER)
    return 0;

#ifdef NO_NETWORK_COLLISIONS
if( (i1==TYPE_CAR || IS_CAR_BODY(i1)) && (i2==TYPE_CAR || IS_CAR_BODY(i2) ) )
    return 0;
#endif


if( (i1==TYPE_CAR || IS_CAR_BODY(i1)) &&
    is_box(i2) && !raydium_ode_network_element_isdistant(e1))
    {
    col_car_box(e1,e2);
    return 0;
    }

if( (i2==TYPE_CAR|| IS_CAR_BODY(i2)) &&
    is_box(i1) && !raydium_ode_network_element_isdistant(e2))
    {
    col_car_box(e2,e1);
    return 0;   
    }

if(is_box(i1)) return 0;
if(is_box(i2)) return 0;
*/
in_red=0;
return 1;
}

char nearcall(int obj1, int obj2)
{
if((obj1==portalbox && obj2==portal1) || (obj1==portal1 && obj2==portalbox))
{
    //raydium_log("CERCA");
    teletransport1();
    return 1;
}

if((obj1==portalbox && obj2==portal2) || (obj1==portal2 && obj2==portalbox))
{
    //raydium_log("CERCA");
    teletransport2();
    return 1;
}

return 0;
}


void shaders()
{

    raydium_shader_load("shader2","bump.vert","bump.frag");
    raydium_shader_var_i_name("shader2","normalMap",0);
    raydium_shader_var_i_name("shader2","colorMap",1);
    raydium_shader_var_4f_name("shader2","specular",0.1,0.1,0.1,1);
    raydium_shader_var_f_name("shader2","shininess",30);
   
    raydium_shader_load("shader3","parabump.vert","parabump.frag");
    raydium_shader_var_i_name("shader3","Normal",0);
    raydium_shader_var_i_name("shader3","Base_Height",1);
    raydium_shader_var_f_name("shader3","u_invRad",0.03);
    raydium_shader_var_2f_name("shader3","cBumpSize",0.042,-0.050);
    raydium_shader_var_i_name("shader3","base_tex",2);
   
    raydium_shader_attach_texture_name("shader2","ladrillosNormalMap.tga");
    raydium_shader_attach_texture_name("shader3","ladrillos.tga");
}

void create_portals()
{
    portal1=raydium_ode_object_find("P1");
    portal1=raydium_ode_object_create ("P1");
        //BEWARE, IT's STATIC, not STANDARD
    raydium_ode_object_box_add("portal1",portal1,1,2.26,2.26,2.26,RAYDIUM_ODE_STATIC,TYPE_PORTAL1,"portal2.tri");
    raydium_ode_object_move_3f (portal1,10,0,0);
   
    portal2=raydium_ode_object_find("P2");
    portal2=raydium_ode_object_create ("P2");
        //BEWARE, IT's STATIC, not STANDARD
    raydium_ode_object_box_add("portal2",portal2,1,2.26,2.26,2.26,RAYDIUM_ODE_STATIC,TYPE_PORTAL2,"portal3.tri");
    raydium_ode_object_move_3f (portal2,12,4,0);
}

void create_portalbox()
{
    raydium_ode_object_create ("PB");
    portalbox=raydium_ode_object_find("PB");
        //BEWARE, IT's STATIC, not STANDARD
    raydium_ode_object_box_add("portalbox",portalbox,0.1,RAYDIUM_ODE_AUTODETECT,0,0,RAYDIUM_ODE_STATIC,TYPE_BOX,"portal-box.tri");
    raydium_ode_object_move_3f (portalbox,0.5,0,1);
}

void update_portalbox()
{
    raydium_ode_object_move_3f (portalbox,pb_x,pb_y,pb_z);
    teletransporting=0;
}

void create_bodycam()
{
    bodycam=raydium_ode_object_find("CAMERA");

    raydium_ode_object_sphere_add("bodycam",bodycam,0.1,1,RAYDIUM_ODE_STANDARD,0,"");
//    raydium_ode_element_move_name_3f("sphere",0,0,1);
   
    //raydium_ode_object_move_3f (bodycam,1,1,1);
}
void update_bodycam()
{
    //float x,y,z;
    //raydium_camera_freemove_get_3f_pos(x,y,z);

    raydium_ode_object_move_3f (bodycam,rffp_cam_pos_x,rffp_cam_pos_y,rffp_cam_pos_z);
}
void create_ball()
{
    ball=raydium_ode_object_find("GLOBAL");
    raydium_ode_object_sphere_add("ball",ball,0.1,RAYDIUM_ODE_AUTODETECT,RAYDIUM_ODE_STANDARD,0,"ballon_big.tri");
//    raydium_ode_element_move_name_3f("sphere",0,0,1);
    raydium_ode_object_move_3f (ball,1,1,1);
}

void input_debuging()
{
    if(raydium_key_last==1000+'D')
        debug=debug?0:1;
}
void render_debug(void)
{
    if(debug)
        raydium_ode_draw_all(RAYDIUM_ODE_DRAW_DEBUG);
}

void display(void)
{

//clearing the screen
raydium_clear_frame();

//call the "magic" function
raydium_camera_freemove(1);

//update_bodycam();

input_debuging();

//moving portalbox (absolute positioning)
if(raydium_key_last==1027)
    exit(0);
if(raydium_key_last==1000+'p')
    create_portals();
if(raydium_key_last==1000+'b')
    create_ball();
if(raydium_key_last==1000+'w')
    pb_x+=0.3;
if(raydium_key_last==1000+'s')
    pb_x-=0.3;
if(raydium_key_last==1000+'a')
    pb_y+=0.3;
if(raydium_key_last==1000+'d')
    pb_y-=0.3;   
update_portalbox();

//drawing everything 3D
raydium_ode_draw_all(0);

//drawing OSD(over 3D)
raydium_osd_printf(2,94,18,0.5,"font2.tga","Press 'D' ('d'+shift) for toogle view debug.");
raydium_osd_printf(2,97,18,0.5,"font2.tga","Press 'a','w','s','d' to move \"The box\"");
if(in_red)
{
    raydium_osd_printf(2,91,18,0.5,"font2.tga","Into the Portal Area");
}
//drawing debug info(over OSD and 3D)
render_debug();

//finishing the render of the frame
raydium_rendering_finish();
}

int main(int argc, char **argv)
{
raydium_init_args(argc,argv);
raydium_init_load("portal.config");
raydium_ode_ground_set_name("portal_terrain.tri");

//various stuff. ignore
//create_ball();
//create_bodycam();
//shaders();

create_portals();
create_portalbox();

raydium_shadow_enable();

raydium_ode_CollideCallback=collide;
raydium_ode_ObjectNearCollide=nearcall;

raydium_callback(&display);
return(0);
}

// EOF


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 29 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 4 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:  
Powered by phpBB® Forum Software © phpBB Group