From 2572b9f72c8f10b01de949e59b481ac5a587aca4 Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Thu, 30 Nov 2006 00:19:27 +0000 Subject: [PATCH] Reserved some Bullet 2.x constraint data. Although we will delay the main Rigid Body user interface after 2.43 release early 2007, I need some constraint data/UI to make progress with COLLADA Physics. Added RigidBody constraint UI LR_ALTKEY+LR_CTRLKEY+LR_SHIFTKEY+ P will bake rigidbody Contribution by RCRuiz, Ramon Carlos. --- source/blender/blenkernel/intern/constraint.c | 41 ++- source/blender/blenloader/intern/readfile.c | 13 + source/blender/blenloader/intern/writefile.c | 3 + source/blender/include/butspace.h | 1 + .../blender/makesdna/DNA_constraint_types.h | 27 +- source/blender/src/buttons_object.c | 109 +++++- source/blender/src/space.c | 76 ++++ .../BlenderRoutines/BL_KetsjiEmbedStart.cpp | 348 +++++++++++++++++- .../Converter/BL_BlenderDataConversion.cpp | 149 ++++++++ .../Converter/KX_BlenderSceneConverter.cpp | 4 +- .../Converter/KX_BlenderSceneConverter.h | 2 +- .../GamePlayer/ghost/GPG_Application.cpp | 2 +- source/gameengine/Ketsji/KX_ISceneConverter.h | 2 +- source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 4 +- source/gameengine/Ketsji/KX_KetsjiEngine.h | 2 +- 15 files changed, 772 insertions(+), 11 deletions(-) diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index d299acb79ab..d471e9c7539 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -723,7 +723,40 @@ void *new_constraint_data (short type) result = data; } break; - default: + case CONSTRAINT_TYPE_RIGIDBODYJOINT: + { + bRigidBodyJointConstraint *data; + int i; + Base *base_iter; + + data = MEM_callocN(sizeof(bRigidBodyJointConstraint), "RigidBodyToConstraint"); + base_iter = G.scene->base.first; + while( base_iter && !data->tar ) { + if( ( ( base_iter->flag & SELECT ) && +// ( base_iter->lay & G.vd->lay ) ) && + ( base_iter != G.scene->basact ) ) + ) + data->tar=base_iter->object; + base_iter = base_iter->next; + } + data->type=1; + data->pivX=0.0; + data->pivY=0.0; + data->pivZ=0.0; + data->axX=0.0; + data->axY=0.0; + data->axZ=1.0; + for (i=0;i<6;i++) + { + data->minLimit[i]=0.0; + data->maxLimit[i]=0.0; + } + data->extraFz=0.0; + result = data; + } + break; + + default: result = NULL; break; } @@ -2014,6 +2047,12 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype, VecMulf(ob->obmat[2], size[2]/obsize[2]); } break; + case CONSTRAINT_TYPE_RIGIDBODYJOINT: + { + + + } + break; default: printf ("Error: Unknown constraint type\n"); break; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index c78ad8d23d1..d33fa6334b4 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -1690,6 +1690,13 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist) data= ((bSizeLimitConstraint*)con->data); }; break; + case CONSTRAINT_TYPE_RIGIDBODYJOINT: + { + bRigidBodyJointConstraint *data; + data= ((bRigidBodyJointConstraint*)con->data); + data->tar = newlibadr(fd, id->lib, data->tar); + }; + break; case CONSTRAINT_TYPE_NULL: break; @@ -6589,6 +6596,12 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb) expand_doit(fd, mainvar, data->tar); break; } + case CONSTRAINT_TYPE_RIGIDBODYJOINT: + { + bRigidBodyJointConstraint *data = (bRigidBodyJointConstraint*)curcon->data; + expand_doit(fd, mainvar, data->tar); + break; + } case CONSTRAINT_TYPE_NULL: break; default: diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index fa454289b5b..3ca85eed67d 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -741,6 +741,9 @@ static void write_constraints(WriteData *wd, ListBase *conlist) case CONSTRAINT_TYPE_SIZELIMIT: writestruct(wd, DATA, "bSizeLimitConstraint", 1, con->data); break; + case CONSTRAINT_TYPE_RIGIDBODYJOINT: + writestruct(wd, DATA, "bRigidBodyJointConstraint", 1, con->data); + break; default: break; } diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index 46c6d7b6696..44432c4a3eb 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -639,6 +639,7 @@ enum { B_CONSTRAINT_ADD_LOCLIMIT, B_CONSTRAINT_ADD_ROTLIMIT, B_CONSTRAINT_ADD_SIZELIMIT, + B_CONSTRAINT_ADD_RIGIDBODYJOINT, B_CONSTRAINT_INF }; diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index fcfbe5790dc..5e220e40fed 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -194,6 +194,26 @@ typedef struct bSizeLimitConstraint{ short pad1; } bSizeLimitConstraint; +/* Rigid Body constraint */ +typedef struct bRigidBodyJointConstraint{ + Object *tar; + Object *child; + int type; + float pivX; + float pivY; + float pivZ; + float axX; + float axY; + float axZ; + float minLimit[6]; + float maxLimit[6]; + float extraFz; + short flag; + short pad; + short pad1; + short pad2; +} bRigidBodyJointConstraint; + /* bConstraint.type */ #define CONSTRAINT_TYPE_NULL 0 #define CONSTRAINT_TYPE_CHILDOF 1 /* Unimplemented */ @@ -212,7 +232,7 @@ typedef struct bSizeLimitConstraint{ #define CONSTRAINT_TYPE_DISTANCELIMIT 14 #define CONSTRAINT_TYPE_STRETCHTO 15 /* claiming this to be mine :) is in tuhopuu bjornmose */ #define CONSTRAINT_TYPE_MINMAX 16 /* floor constraint */ - +#define CONSTRAINT_TYPE_RIGIDBODYJOINT 17 /* rigidbody constraint */ /* bConstraint.flag */ /* expand for UI */ @@ -298,5 +318,10 @@ typedef struct bSizeLimitConstraint{ #define LIMIT_NOPARENT 0x01 +#define CONSTRAINT_RB_BALL 1 +#define CONSTRAINT_RB_HINGE 2 +#define CONSTRAINT_RB_GENERIC6DOF 3 +#define CONSTRAINT_RB_VEHICLE 11 + #endif diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 39ca3703cd9..77338241f2d 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -368,6 +368,9 @@ void get_constraint_typestring (char *str, void *con_v) case CONSTRAINT_TYPE_SIZELIMIT: strcpy (str, "Limit Scale"); return; + case CONSTRAINT_TYPE_RIGIDBODYJOINT: + strcpy (str, "Rigid Body"); + return; default: strcpy (str, "Unknown"); return; @@ -405,6 +408,8 @@ static int get_constraint_col(bConstraint *con) return TH_BUT_POPUP; case CONSTRAINT_TYPE_SIZELIMIT: return TH_BUT_POPUP; + case CONSTRAINT_TYPE_RIGIDBODYJOINT: + return TH_BUT_SETTING; default: return TH_REDALERT; } @@ -1126,6 +1131,97 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s uiBlockEndAlign(block); } break; + case CONSTRAINT_TYPE_RIGIDBODYJOINT: + { + bRigidBodyJointConstraint *data = con->data; + int togButWidth = 70; + int offsetY = 150; + float extremeLin = 1000.f; + float extremeAngX = 180.f; + float extremeAngY = 45.f; + float extremeAngZ = 45.f; + + int textButWidth = ((width/2)-togButWidth); + + uiDefButS(block, MENU, B_SWITCHRENDER, "Joint Types%t|Ball%x1|Hinge%x2|Generic6DOF%x3",//|Extra Force%x6", + *xco, *yco-25, 150, 18, &data->type, 0, 0, 0, 0, "Choose the joint type"); + height = 310; + + uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); + { + //uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "Child:", *xco, *yco-50, 130, 18, &data->tar, "Child Object"); + //if (data->tar) + // uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "Child:", *xco+135, *yco-50, 130, 18, &data->child, "Child2 Object (if this exist then this object will be the pivot Only)"); + uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Pivot X:", *xco, *yco-75, 130, 18, &data->pivX, -10000, 10000, 100.0, 0.0, "Offset Joint"); + uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Pivot Y:", *xco, *yco-100, 130, 18, &data->pivY, -10000, 10000, 100.0, 0.0, "Offset Joint"); + uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Pivot Z:", *xco, *yco-125, 130, 18, &data->pivZ, -10000, 10000, 100.0, 0.0, "Offset Joint"); + uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Ax X:", *xco+135, *yco-75, 130, 18, &data->axX, -10000, 10000, 100.0, 0.0, "Offset Joint"); + uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Ax Y:", *xco+135, *yco-100, 130, 18, &data->axY, -10000, 10000, 100.0, 0.0, "Offset Joint"); + uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Ax Z:", *xco+135, *yco-125, 130, 18, &data->axZ, -10000, 10000, 100.0, 0.0, "Offset Joint"); + + /* Draw Pairs of LimitToggle+LimitValue */ + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, LIMIT_XMIN, B_CONSTRAINT_TEST, "LinMinX", *xco, *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum x limit"); + uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-offsetY, (textButWidth-5), 18, &(data->minLimit[0]), -extremeLin, extremeLin, 0.1,0.5,"min x limit"); + uiBlockEndAlign(block); + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, LIMIT_XMIN, B_CONSTRAINT_TEST, "LinMaxX", *xco+(width-(textButWidth-5)-togButWidth), *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum x limit"); + uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-offsetY, (textButWidth-5), 18, &(data->maxLimit[0]), -extremeLin, extremeLin, 0.1,0.5,"max x limit"); + uiBlockEndAlign(block); + offsetY += 20; + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, LIMIT_YMIN, B_CONSTRAINT_TEST, "LinMinY", *xco, *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum y limit"); + uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-offsetY, (textButWidth-5), 18, &(data->minLimit[1]), -extremeLin, extremeLin, 0.1,0.5,"min y limit"); + uiBlockEndAlign(block); + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, LIMIT_YMIN, B_CONSTRAINT_TEST, "LinMaxY", *xco+(width-(textButWidth-5)-togButWidth), *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum y limit"); + uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-offsetY, (textButWidth-5), 18, &(data->maxLimit[1]), -extremeLin, extremeLin, 0.1,0.5,"max y limit"); + uiBlockEndAlign(block); + offsetY += 20; + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, LIMIT_ZMIN, B_CONSTRAINT_TEST, "LinMinZ", *xco, *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum z limit"); + uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-offsetY, (textButWidth-5), 18, &(data->minLimit[2]), -extremeLin, extremeLin, 0.1,0.5,"min z limit"); + uiBlockEndAlign(block); + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, LIMIT_ZMIN, B_CONSTRAINT_TEST, "LinMaxZ", *xco+(width-(textButWidth-5)-togButWidth), *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum z limit"); + uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-offsetY, (textButWidth-5), 18, &(data->maxLimit[2]), -extremeLin, extremeLin, 0.1,0.5,"max z limit"); + uiBlockEndAlign(block); + offsetY += 20; + + /* Draw Pairs of LimitToggle+LimitValue */ + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, LIMIT_XMAX, B_CONSTRAINT_TEST, "AngMinX", *xco, *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum x limit"); + uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-offsetY, (textButWidth-5), 18, &(data->minLimit[3]), -extremeAngX, extremeAngX, 0.1,0.5,"min x limit"); + uiBlockEndAlign(block); + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, LIMIT_XMAX, B_CONSTRAINT_TEST, "AngMaxX", *xco+(width-(textButWidth-5)-togButWidth), *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum x limit"); + uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-offsetY, (textButWidth-5), 18, &(data->maxLimit[3]), -extremeAngX, extremeAngX, 0.1,0.5,"max x limit"); + uiBlockEndAlign(block); + offsetY += 20; + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, LIMIT_YMAX, B_CONSTRAINT_TEST, "AngMinY", *xco, *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum y limit"); + uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-offsetY, (textButWidth-5), 18, &(data->minLimit[4]), -extremeAngY, extremeAngY, 0.1,0.5,"min y limit"); + uiBlockEndAlign(block); + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, LIMIT_YMAX, B_CONSTRAINT_TEST, "AngMaxY", *xco+(width-(textButWidth-5)-togButWidth), *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum y limit"); + uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-offsetY, (textButWidth-5), 18, &(data->maxLimit[4]), -extremeAngY, extremeAngY, 0.1,0.5,"max y limit"); + uiBlockEndAlign(block); + offsetY += 20; + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, LIMIT_ZMAX, B_CONSTRAINT_TEST, "AngMinZ", *xco, *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum z limit"); + uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-offsetY, (textButWidth-5), 18, &(data->minLimit[5]), -extremeAngZ, extremeAngZ, 0.1,0.5,"min z limit"); + uiBlockEndAlign(block); + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, LIMIT_ZMAX, B_CONSTRAINT_TEST, "AngMaxZ", *xco+(width-(textButWidth-5)-togButWidth), *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum z limit"); + uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-offsetY, (textButWidth-5), 18, &(data->maxLimit[5]), -extremeAngZ, extremeAngZ, 0.1,0.5,"max z limit"); + uiBlockEndAlign(block); + + + } + + } + break; case CONSTRAINT_TYPE_NULL: { height = 17; @@ -1141,7 +1237,7 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s (*yco)-=(24+height); } - if (con->type!=CONSTRAINT_TYPE_NULL) { + if ((con->type!=CONSTRAINT_TYPE_NULL)&&(con->type!=CONSTRAINT_TYPE_RIGIDBODYJOINT)) { uiBlockBeginAlign(block); uiDefButF(block, NUMSLI, B_CONSTRAINT_INF, "Influence ", *xco, *yco, 197, 20, &(con->enforce), 0.0, 1.0, 0.0, 0.0, "Amount of influence this constraint will have on the final solution"); but = uiDefBut(block, BUT, B_CONSTRAINT_TEST, "Show", *xco+200, *yco, 45, 20, 0, 0.0, 1.0, 0.0, 0.0, "Show constraint's ipo in the Ipo window, adds a channel if not there"); @@ -1190,6 +1286,8 @@ static uiBlock *add_constraintmenu(void *arg_unused) uiDefBut(block, BUTM, B_CONSTRAINT_ADD_STRETCHTO,"Stretch To", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, ""); + uiDefBut(block, BUTM, B_CONSTRAINT_ADD_RIGIDBODYJOINT,"Rigid Body Joint", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");//rcruiz + if (ob->flag & OB_POSEMODE) { uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, ""); @@ -1362,6 +1460,15 @@ void do_constraintbuts(unsigned short event) BIF_undo_push("Add constraint"); } break; + case B_CONSTRAINT_ADD_RIGIDBODYJOINT: + { + bConstraint *con; + con = add_new_constraint(CONSTRAINT_TYPE_RIGIDBODYJOINT); + add_constraint_to_active(ob, con); + + BIF_undo_push("Add constraint"); + } + break; default: break; diff --git a/source/blender/src/space.c b/source/blender/src/space.c index b9bce7b60e0..d6307c7e284 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -169,6 +169,7 @@ extern void StartKetsjiShell(ScrArea *area, char* startscenename, struct Main* maggie, struct SpaceIpo* sipo,int always_use_expand_framing); +extern void StartKetsjiShellSimulation(ScrArea *area, char* startscenename, struct Main* maggie, struct SpaceIpo* sipo,int always_use_expand_framing);//rcruiz /** * When the mipmap setting changes, we want to redraw the view right @@ -541,6 +542,78 @@ void start_game(void) #endif } +void start_RBSimulation(void) +{ +#if GAMEBLENDER == 1 +#ifndef NO_KETSJI + Scene *sc, *startscene = G.scene; + LinkNode *scene_cfra_store; + + /* XXX, silly code - the game engine can + * access any scene through logic, so we try + * to make sure each scene has a valid camera, + * just in case the game engine tries to use it. + * + * Better would be to make a better routine + * in the game engine for finding the camera. + * - zr + * Note: yes, this is all very badly hacked! (ton) + */ + for (sc= G.main->scene.first; sc; sc= sc->id.next) { + if (!sc->camera) { + Base *base; + + for (base= sc->base.first; base; base= base->next) + if (base->object->type==OB_CAMERA) + break; + + sc->camera= base?base->object:NULL; + } + } + + /* these two lines make sure front and backbuffer are equal. for swapbuffers */ + markdirty_all(); + screen_swapbuffers(); + + /* can start from header */ + mywinset(curarea->win); + + scene_cfra_store= save_and_reset_all_scene_cfra(); + + + /* game engine will do its own sounds. */ + sound_stop_all_sounds(); + sound_exit_audio(); + + /* Before jumping into Ketsji, we configure some settings. */ + space_set_commmandline_options(); + + SaveState(); + StartKetsjiShellSimulation(curarea, startscene->id.name+2, G.main,G.sipo, 1); + RestoreState(); + /* Restart BPY - unload the game engine modules. */ + BPY_end_python(); + BPY_start_python(0, NULL); /* argc, argv stored there already */ + BPY_post_start_python(); /* userpref path and menus init */ + + restore_all_scene_cfra(scene_cfra_store); + set_scene_bg(startscene); + scene_update_for_newframe(G.scene, G.scene->lay); + + if (G.flags & G_FILE_AUTOPLAY) + exit_usiblender(); + + /* groups could have changed ipo */ + allqueue(REDRAWNLA, 0); + allqueue(REDRAWACTION, 0); + allspace(REMAKEIPO, 0); + allqueue(REDRAWIPO, 0); +#endif +#else + notice("YOU NEED GAME ENGIEN TO RUN THE SIMULATION!"); +#endif +} + static void changeview3dspace(ScrArea *sa, void *spacedata) { setwinmatrixview3d(sa->winx, sa->winy, NULL); /* 0= no pick rect */ @@ -1771,6 +1844,9 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) clear_parent(); else if(G.qual==(LR_ALTKEY|LR_CTRLKEY)) make_proxy(); + else if(G.qual==(LR_ALTKEY|LR_CTRLKEY|LR_SHIFTKEY)) { + start_RBSimulation(); + } else if((G.qual==0) && (OBACT) && (OBACT->type==OB_ARMATURE) && (OBACT->flag & OB_POSEMODE)) select_bone_parent(); else if((G.qual==0)) { diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index a270b73c80d..b886e4ff54a 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -348,7 +348,7 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, rasterizer->Init(); // start the engine - ketsjiengine->StartEngine(); + ketsjiengine->StartEngine(true); // the mainloop while (!exitrequested) @@ -449,3 +449,349 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, if (bfd) BLO_blendfiledata_free(bfd); } +#ifdef __cplusplus +extern "C" { +#endif +#include "BSE_headerbuttons.h" +void update_for_newframe(); +#ifdef __cplusplus +} +#endif + +extern "C" void StartKetsjiShellSimulation(struct ScrArea *area, + char* scenename, + struct Main* maggie, + struct SpaceIpo *sipo, + int always_use_expand_framing) +{ + int exitrequested = KX_EXIT_REQUEST_NO_REQUEST; + + Main* blenderdata = maggie; + + char* startscenename = scenename; + char pathname[160]; + strcpy (pathname, maggie->name); + STR_String exitstring = ""; + BlendFileData *bfd= NULL; + + bgl::InitExtensions(1); + + do + { +// View3D *v3d= (View3D*) area->spacedata.first; + + // get some preferences + SYS_SystemHandle syshandle = SYS_GetSystem(); + bool properties = (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0); + bool usefixed = (SYS_GetCommandLineInt(syshandle, "fixedtime", 0) != 0); + bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0); + bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0); + bool game2ipo = true;//(SYS_GetCommandLineInt(syshandle, "game2ipo", 0) != 0); + bool displaylists = (SYS_GetCommandLineInt(syshandle, "displaylists", 0) != 0); + bool usemat = false; + +/* #ifdef GL_ARB_multitexture + if(bgl::RAS_EXT_support._ARB_multitexture && bgl::QueryVersion(1, 1)) { + usemat = (SYS_GetCommandLineInt(syshandle, "blender_material", 0) != 0); + int unitmax=0; + glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, (GLint*)&unitmax); + bgl::max_texture_units = MAXTEX>unitmax?unitmax:MAXTEX; + //std::cout << "using(" << bgl::max_texture_units << ") of(" << unitmax << ") texture units." << std::endl; + } else { + bgl::max_texture_units = 0; + } + #endif + +*/ + // create the canvas, rasterizer and rendertools + RAS_ICanvas* canvas = new KX_BlenderCanvas(area); + //canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE); + RAS_IRenderTools* rendertools = new KX_BlenderRenderTools(); + RAS_IRasterizer* rasterizer = NULL; + + // let's see if we want to use vertexarrays or not + int usevta = SYS_GetCommandLineInt(syshandle,"vertexarrays",1); + bool useVertexArrays = (usevta > 0); + + bool lock_arrays = (displaylists && useVertexArrays); + + if(displaylists && !useVertexArrays) + rasterizer = new RAS_ListRasterizer(canvas); + else if (useVertexArrays && bgl::QueryVersion(1, 1)) + rasterizer = new RAS_VAOpenGLRasterizer(canvas, lock_arrays); + else + rasterizer = new RAS_OpenGLRasterizer(canvas); + + // create the inputdevices + KX_BlenderKeyboardDevice* keyboarddevice = new KX_BlenderKeyboardDevice(); + KX_BlenderMouseDevice* mousedevice = new KX_BlenderMouseDevice(); + + // create a networkdevice + NG_NetworkDeviceInterface* networkdevice = new + NG_LoopBackNetworkDeviceInterface(); + + // get an audiodevice + SND_DeviceManager::Subscribe(); + SND_IAudioDevice* audiodevice = SND_DeviceManager::Instance(); + audiodevice->UseCD(); + + // create a ketsji/blendersystem (only needed for timing and stuff) + KX_BlenderSystem* kxsystem = new KX_BlenderSystem(); + + // create the ketsjiengine + KX_KetsjiEngine* ketsjiengine = new KX_KetsjiEngine(kxsystem); + +/* // set the devices + ketsjiengine->SetKeyboardDevice(keyboarddevice); + ketsjiengine->SetMouseDevice(mousedevice); + ketsjiengine->SetNetworkDevice(networkdevice); + ketsjiengine->SetCanvas(canvas); + ketsjiengine->SetRenderTools(rendertools); + ketsjiengine->SetRasterizer(rasterizer); + ketsjiengine->SetNetworkDevice(networkdevice); + ketsjiengine->SetAudioDevice(audiodevice); + ketsjiengine->SetUseFixedTime(usefixed); + ketsjiengine->SetTimingDisplay(frameRate, profile, properties); + +*/ + + // some blender stuff + MT_CmMatrix4x4 projmat; + MT_CmMatrix4x4 viewmat; + int i; + +/* for (i = 0; i < 16; i++) + { + float *viewmat_linear= (float*) v3d->viewmat; + viewmat.setElem(i, viewmat_linear[i]); + } + for (i = 0; i < 16; i++) + { + float *projmat_linear = (float*) area->winmat; + projmat.setElem(i, projmat_linear[i]); + } +*/ +/* float camzoom = (1.41421 + (v3d->camzoom / 50.0)); + camzoom *= camzoom; + camzoom = 4.0 / camzoom; +*/ +// ketsjiengine->SetDrawType(v3d->drawtype); +// ketsjiengine->SetCameraZoom(camzoom); +/* + // if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file + if (exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME || exitrequested == KX_EXIT_REQUEST_RESTART_GAME) + { + exitrequested = KX_EXIT_REQUEST_NO_REQUEST; + if (bfd) BLO_blendfiledata_free(bfd); + + char basedpath[160]; + // base the actuator filename with respect + // to the original file working directory + if (exitstring != "") + strcpy(basedpath, exitstring.Ptr()); + + BLI_convertstringcode(basedpath, pathname, 0); + bfd = load_game_data(basedpath); + + // if it wasn't loaded, try it forced relative + if (!bfd) + { + // just add "//" in front of it + char temppath[162]; + strcpy(temppath, "//"); + strcat(temppath, basedpath); + + BLI_convertstringcode(temppath, pathname, 0); + bfd = load_game_data(temppath); + } + + // if we got a loaded blendfile, proceed + if (bfd) + { + blenderdata = bfd->main; + startscenename = bfd->curscene->id.name + 2; + } + // else forget it, we can't find it + else + { + exitrequested = KX_EXIT_REQUEST_QUIT_GAME; + } + } +*/ + Scene *blscene = NULL; + if (!bfd) + { + blscene = (Scene*) maggie->scene.first; + for (Scene *sce= (Scene*) maggie->scene.first; sce; sce= (Scene*) sce->id.next) + { + if (startscenename == (sce->id.name+2)) + { + blscene = sce; + break; + } + } + } else { + blscene = bfd->curscene; + } + int cframe,startFrame; + if (blscene) + { + cframe=blscene->r.cfra; + startFrame = blscene->r.sfra; + blscene->r.cfra=startFrame; + update_for_newframe(); + ketsjiengine->SetGame2IpoMode(game2ipo,startFrame); + } + + // Quad buffered needs a special window. + if (blscene->r.stereomode != RAS_IRasterizer::RAS_STEREO_QUADBUFFERED) + rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) blscene->r.stereomode); + + if (exitrequested != KX_EXIT_REQUEST_QUIT_GAME) + { + /*if (v3d->persp != 2) + { + ketsjiengine->EnableCameraOverride(startscenename); + ketsjiengine->SetCameraOverrideUseOrtho((v3d->persp == 0)); + ketsjiengine->SetCameraOverrideProjectionMatrix(projmat); + ketsjiengine->SetCameraOverrideViewMatrix(viewmat); + }*/ + + // create a scene converter, create and convert the startingscene + KX_ISceneConverter* sceneconverter = new KX_BlenderSceneConverter(maggie,sipo, ketsjiengine); + ketsjiengine->SetSceneConverter(sceneconverter); + + if (always_use_expand_framing) + sceneconverter->SetAlwaysUseExpandFraming(true); + + if(usemat) + sceneconverter->SetMaterials(true); + + KX_Scene* startscene = new KX_Scene(keyboarddevice, + mousedevice, + networkdevice, + audiodevice, + startscenename); + + // some python things + PyObject* dictionaryobject = initGamePythonScripting("Ketsji", psl_Lowest); + ketsjiengine->SetPythonDictionary(dictionaryobject); + initRasterizer(rasterizer, canvas); + PyObject *gameLogic = initGameLogic(startscene); + initGameKeys(); + initPythonConstraintBinding(); + + if (sceneconverter) + { + // convert and add scene + sceneconverter->ConvertScene( + startscenename, + startscene, + dictionaryobject, + keyboarddevice, + rendertools, + canvas); + ketsjiengine->AddScene(startscene); + + // init the rasterizer + //rasterizer->Init(); + + // start the engine + ketsjiengine->StartEngine(false); + + // the mainloop + while ((blscene->r.cfra<=blscene->r.efra)&&(!exitrequested)) + { + printf("frame %i\n",blscene->r.cfra); + // first check if we want to exit + exitrequested = ketsjiengine->GetExitCode(); + + // kick the engine + ketsjiengine->NextFrame(); + blscene->r.cfra=blscene->r.cfra+1; + update_for_newframe(); + // render the frame + //ketsjiengine->Render(); + + // test for the ESC key + /*while (qtest()) + { + short val; + unsigned short event = extern_qread(&val); + + if (keyboarddevice->ConvertBlenderEvent(event,val)) + exitrequested = KX_EXIT_REQUEST_BLENDER_ESC; + + if (event==MOUSEX) { + val = val - scrarea_get_win_x(area); + } else if (event==MOUSEY) { + val = scrarea_get_win_height(area) - (val - scrarea_get_win_y(area)) - 1; + } + + mousedevice->ConvertBlenderEvent(event,val); + }*/ + } + exitstring = ketsjiengine->GetExitString(); + // when exiting the mainloop + //dictionaryClearByHand(gameLogic); + //ketsjiengine->StopEngine(); + //exitGamePythonScripting(); + //networkdevice->Disconnect(); + } + if (sceneconverter) + { + delete sceneconverter; + sceneconverter = NULL; + } + } + blscene->r.cfra=cframe; + // set the cursor back to normal + canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL); + + // clean up some stuff + audiodevice->StopCD(); + if (ketsjiengine) + { + delete ketsjiengine; + ketsjiengine = NULL; + } + if (kxsystem) + { + delete kxsystem; + kxsystem = NULL; + } + if (networkdevice) + { + delete networkdevice; + networkdevice = NULL; + } + if (keyboarddevice) + { + delete keyboarddevice; + keyboarddevice = NULL; + } + if (mousedevice) + { + delete mousedevice; + mousedevice = NULL; + } + /*if (rasterizer) + { + delete rasterizer; + rasterizer = NULL; + } + if (rendertools) + { + delete rendertools; + rendertools = NULL; + } + if (canvas) + { + delete canvas; + canvas = NULL; + }*/ + SND_DeviceManager::Unsubscribe(); + + } while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME); + if (bfd) BLO_blendfiledata_free(bfd); +} \ No newline at end of file diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index b0986aeca50..de20789235d 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -1515,6 +1515,84 @@ static struct Scene *GetSceneForName(struct Main *maggie, const STR_String& scen return (Scene*) maggie->scene.first; } +#include "DNA_constraint_types.h" +#include "BIF_editconstraint.h" + +bPoseChannel *get_active_posechannel2 (Object *ob) +{ + bArmature *arm= (bArmature*)ob->data; + bPoseChannel *pchan; + + /* find active */ + for(pchan= (bPoseChannel *)ob->pose->chanbase.first; pchan; pchan= pchan->next) { + if(pchan->bone && (pchan->bone->flag & BONE_ACTIVE) && (pchan->bone->layer & arm->layer)) + return pchan; + } + + return NULL; +} + +ListBase *get_active_constraints2(Object *ob) +{ + if (!ob) + return NULL; + + if (ob->flag & OB_POSEMODE) { + bPoseChannel *pchan; + + pchan = get_active_posechannel2(ob); + if (pchan) + return &pchan->constraints; + } + else + return &ob->constraints; + + return NULL; +} + + +void RBJconstraints(Object *ob)//not used +{ + ListBase *conlist; + bConstraint *curcon; + + conlist = get_active_constraints2(ob); + + if (conlist) { + for (curcon = (bConstraint *)conlist->first; curcon; curcon=(bConstraint *)curcon->next) { + + printf("%i\n",curcon->type); + } + + + } +} + +#include "PHY_IPhysicsEnvironment.h" +#include "KX_IPhysicsController.h" +#include "PHY_DynamicTypes.h" + +KX_IPhysicsController* getPhId(CListValue* sumolist,STR_String busc){//not used + + for (int j=0;jGetCount();j++) + { + KX_GameObject* gameobje = (KX_GameObject*) sumolist->GetValue(j); + if (gameobje->GetName()==busc) + return gameobje->GetPhysicsController(); + } + +} + +KX_GameObject* getGameOb(STR_String busc,CListValue* sumolist){ + + for (int j=0;jGetCount();j++) + { + KX_GameObject* gameobje = (KX_GameObject*) sumolist->GetValue(j); + if (gameobje->GetName()==busc) + return gameobje; + } + +} // convert blender objects into ketsji gameobjects void BL_ConvertBlenderObjects(struct Main* maggie, @@ -1812,6 +1890,77 @@ void BL_ConvertBlenderObjects(struct Main* maggie, } + // create physics joints + for (i=0;iGetCount();i++) + { + KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); + struct Object* blenderobject = converter->FindBlenderObject(gameobj); + int nummeshes = gameobj->GetMeshCount(); + RAS_MeshObject* meshobj = 0; + ListBase *conlist; + bConstraint *curcon; + conlist = get_active_constraints2(blenderobject); + if (conlist) { + for (curcon = (bConstraint *)conlist->first; curcon; curcon=(bConstraint *)curcon->next) { + if (curcon->type==CONSTRAINT_TYPE_RIGIDBODYJOINT){ + bRigidBodyJointConstraint *dat=(bRigidBodyJointConstraint *)curcon->data; + if (dat->tar) + if (!dat->child){ + KX_GameObject *gotar=getGameOb(dat->tar->id.name,sumolist); + PHY_IPhysicsController* physctrl = (PHY_IPhysicsController*) (int)gameobj->GetPhysicsController()->GetUserData(); + PHY_IPhysicsController* physctr2 = (PHY_IPhysicsController*) (int)gotar->GetPhysicsController()->GetUserData(); + kxscene->GetPhysicsEnvironment()->createConstraint(physctrl,physctr2,(PHY_ConstraintType)dat->type,(float)dat->pivX,(float)dat->pivY,(float)dat->pivZ,(float)dat->axX,(float)dat->axY,(float)dat->axZ); + /*switch(dat->type){ + case CONSTRAINT_RB_BALL: + KX_GameObject *gotar=getGameOb(dat->tar->id.name,sumolist); + PHY_IPhysicsController* physctrl = (PHY_IPhysicsController*) (int)gameobj->GetPhysicsController()->GetUserData(); + PHY_IPhysicsController* physctr2 = (PHY_IPhysicsController*) (int)gotar->GetPhysicsController()->GetUserData(); + kxscene->GetPhysicsEnvironment()->createConstraint(physctrl,physctr2,(PHY_ConstraintType)dat->type,(float)dat->pivX,(float)dat->pivY,(float)dat->pivZ,(float)dat->axX,(float)dat->axY,(float)dat->axZ); + break; + case CONSTRAINT_RB_HINGE: + KX_GameObject *gotar=getGameOb(dat->tar->id.name,sumolist); + PHY_IPhysicsController* physctrl = (PHY_IPhysicsController*) (int)gameobj->GetPhysicsController()->GetUserData(); + PHY_IPhysicsController* physctr2 = (PHY_IPhysicsController*) (int)gotar->GetPhysicsController()->GetUserData(); + kxscene->GetPhysicsEnvironment()->createConstraint(physctrl,physctr2,(PHY_ConstraintType)dat->type,(float)dat->pivX,(float)dat->pivY,(float)dat->pivZ,(float)dat->axX,(float)dat->axY,(float)dat->axZ); + break; + }*/ + } + } + } + } + + } + + //Intento de actualizar posicion + /*for (i=0;iGetCount();i++) + { + KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); + struct Object* blenderobject = converter->FindBlenderObject(gameobj); + + MT_Point3 pos = MT_Point3( + blenderobject->loc[0]+blenderobject->dloc[0], + blenderobject->loc[1]+blenderobject->dloc[1], + blenderobject->loc[2]+blenderobject->dloc[2] + ); + MT_Vector3 eulxyz = MT_Vector3( + blenderobject->rot[0], + blenderobject->rot[1], + blenderobject->rot[2] + ); + MT_Vector3 scale = MT_Vector3( + blenderobject->size[0], + blenderobject->size[1], + blenderobject->size[2] + ); + + gameobj->NodeSetLocalPosition(pos); + gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz)); + gameobj->NodeSetLocalScale(scale); + gameobj->NodeUpdateGS(0,true); + }*/ + //rcruiz> + + templist->Release(); sumolist->Release(); diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp index 83b2a11e606..10f3ea39616 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp @@ -576,7 +576,7 @@ Ipo* KX_BlenderSceneConverter::findIpoForName(char* objName) } -void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo() +void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo) { KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes(); @@ -604,6 +604,7 @@ void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo() if (ipo) { //clear the curve data + if (clearIpo){ IpoCurve *icu1; int numCurves = 0; for( icu1 = (IpoCurve*)ipo->curve.first; icu1; ) { @@ -618,6 +619,7 @@ void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo() MEM_freeN( tmpicu ); localDel_ipoCurve( tmpicu ,m_sipo); } + } } else { ipo = add_ipo(blenderObject->id.name+2, ID_OB); diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.h b/source/gameengine/Converter/KX_BlenderSceneConverter.h index db2090aa470..c4447c53930 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.h +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.h @@ -130,7 +130,7 @@ public: void RegisterWorldInfo(KX_WorldInfo *worldinfo); - virtual void ResetPhysicsObjectsAnimationIpo(); + virtual void ResetPhysicsObjectsAnimationIpo(bool clearIpo); ///this generates ipo curves for position, rotation, allowing to use game physics in animation virtual void WritePhysicsObjectToAnimationIpo(int frameNumber); diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp index 8554b7c85bc..fd47df7f770 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp @@ -673,7 +673,7 @@ bool GPG_Application::startEngine(void) m_frameTimer = m_system->installTimer(0, kTimerFreq, frameTimerProc, m_mainWindow); } m_rasterizer->Init(); - m_ketsjiengine->StartEngine(); + m_ketsjiengine->StartEngine(true); m_engineRunning = true; } diff --git a/source/gameengine/Ketsji/KX_ISceneConverter.h b/source/gameengine/Ketsji/KX_ISceneConverter.h index 52a65791885..8693eb34d6b 100644 --- a/source/gameengine/Ketsji/KX_ISceneConverter.h +++ b/source/gameengine/Ketsji/KX_ISceneConverter.h @@ -61,7 +61,7 @@ public: virtual bool TryAndLoadNewFile() = 0; - virtual void ResetPhysicsObjectsAnimationIpo() = 0; + virtual void ResetPhysicsObjectsAnimationIpo(bool clearIpo) = 0; ///this generates ipo curves for position, rotation, allowing to use game physics in animation virtual void WritePhysicsObjectToAnimationIpo(int frameNumber) = 0; diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 4d6b70a0b3c..6a54c613cc0 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -254,7 +254,7 @@ void KX_KetsjiEngine::SetSceneConverter(KX_ISceneConverter* sceneconverter) * Blender into Ketsji native (realtime) format also sets up the * graphics context */ -void KX_KetsjiEngine::StartEngine() +void KX_KetsjiEngine::StartEngine(bool clearIpo) { m_clockTime = m_kxsystem->GetTimeInSeconds(); m_frameTime = m_kxsystem->GetTimeInSeconds(); @@ -266,7 +266,7 @@ void KX_KetsjiEngine::StartEngine() if (m_game2ipo) { - m_sceneconverter->ResetPhysicsObjectsAnimationIpo(); + m_sceneconverter->ResetPhysicsObjectsAnimationIpo(clearIpo); m_sceneconverter->WritePhysicsObjectToAnimationIpo(m_currentFrame); } diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index d78ad955e1a..ae33e8da998 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -205,7 +205,7 @@ public: void NextFrame(); void Render(); - void StartEngine(); + void StartEngine(bool clearIpo); void StopEngine(); void Export(const STR_String& filename);