Blender V2.61 - r43446

KX_IpoConvert.cpp

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): none yet.
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00033 #if defined(WIN32) && !defined(FREE_WINDOWS)
00034 // don't show stl-warnings
00035 #pragma warning (disable:4786)
00036 #endif
00037 
00038 #include "BKE_material.h" /* give_current_material */
00039 
00040 #include "KX_GameObject.h"
00041 #include "KX_IpoConvert.h"
00042 #include "KX_IInterpolator.h"
00043 #include "KX_ScalarInterpolator.h"
00044 
00045 #include "KX_BlenderScalarInterpolator.h"
00046 #include "KX_BlenderSceneConverter.h"
00047 
00048 
00049 /* This little block needed for linking to Blender... */
00050 #ifdef WIN32
00051 #include "BLI_winstuff.h"
00052 #endif
00053 
00054 #include "DNA_object_types.h"
00055 #include "DNA_action_types.h"
00056 #include "DNA_anim_types.h"
00057 #include "DNA_ipo_types.h"
00058 #include "DNA_lamp_types.h"
00059 #include "DNA_world_types.h"
00060 #include "DNA_camera_types.h"
00061 #include "DNA_material_types.h"
00062 /* end of blender include block */
00063 
00064 #include "KX_IPO_SGController.h"
00065 #include "KX_LightIpoSGController.h"
00066 #include "KX_CameraIpoSGController.h"
00067 #include "KX_WorldIpoController.h"
00068 #include "KX_ObColorIpoSGController.h"
00069 #include "KX_MaterialIpoController.h"
00070 
00071 #include "SG_Node.h"
00072 
00073 #include "STR_HashedString.h"
00074 
00075 static BL_InterpolatorList *GetAdtList(struct bAction *for_act, KX_BlenderSceneConverter *converter)
00076 {
00077     BL_InterpolatorList *adtList= converter->FindInterpolatorList(for_act);
00078 
00079     if (!adtList) {     
00080         adtList = new BL_InterpolatorList(for_act);
00081         converter->RegisterInterpolatorList(adtList, for_act);
00082     }
00083             
00084     return adtList; 
00085 }
00086 
00087 SG_Controller *BL_CreateIPO(struct bAction *action, KX_GameObject* gameobj, KX_BlenderSceneConverter *converter)
00088 {
00089     KX_IpoSGController* ipocontr = new KX_IpoSGController();
00090     ipocontr->SetGameObject(gameobj);
00091 
00092     Object* blenderobject = gameobj->GetBlenderObject();
00093 
00094     ipocontr->GetIPOTransform().SetPosition(MT_Point3(blenderobject->loc));
00095     ipocontr->GetIPOTransform().SetEulerAngles(MT_Vector3(blenderobject->rot));
00096     ipocontr->GetIPOTransform().SetScaling(MT_Vector3(blenderobject->size));
00097 
00098     const char *rotmode, *drotmode;
00099 
00100     switch(blenderobject->rotmode) {
00101     case ROT_MODE_AXISANGLE:
00102         rotmode = "rotation_axis_angle";
00103         drotmode = "delta_rotation_axis_angle";
00104         break;
00105     case ROT_MODE_QUAT: /* XXX, this isnt working, currently only eulers are supported [#28853] */
00106         rotmode = "rotation_quaternion";
00107         drotmode = "delta_rotation_quaternion";
00108         break;
00109     default:
00110         rotmode = "rotation_euler";
00111         drotmode = "delta_rotation_euler";
00112         break;
00113     }
00114 
00115     BL_InterpolatorList *adtList= GetAdtList(action, converter);
00116         
00117     // For each active channel in the adtList add an
00118     // interpolator to the game object.
00119         
00120     KX_IInterpolator *interpolator;
00121     KX_IScalarInterpolator *interp;
00122         
00123     for(int i=0; i<3; i++) {
00124         if ((interp = adtList->GetScalarInterpolator("location", i))) {
00125             interpolator= new KX_ScalarInterpolator(&(ipocontr->GetIPOTransform().GetPosition()[i]), interp);
00126             ipocontr->AddInterpolator(interpolator);
00127             ipocontr->SetIPOChannelActive(OB_LOC_X+i, true);
00128         }
00129     }
00130     for(int i=0; i<3; i++) {
00131         if ((interp = adtList->GetScalarInterpolator("delta_location", i))) {
00132             interpolator= new KX_ScalarInterpolator(&(ipocontr->GetIPOTransform().GetDeltaPosition()[i]), interp);
00133             ipocontr->AddInterpolator(interpolator);
00134             ipocontr->SetIPOChannelActive(OB_DLOC_X+i, true);
00135         }
00136     }
00137     for(int i=0; i<3; i++) {
00138         if ((interp = adtList->GetScalarInterpolator(rotmode, i))) {
00139             interpolator= new KX_ScalarInterpolator(&(ipocontr->GetIPOTransform().GetEulerAngles()[i]), interp);
00140             ipocontr->AddInterpolator(interpolator);
00141             ipocontr->SetIPOChannelActive(OB_ROT_X+i, true);
00142         }
00143     }
00144     for(int i=0; i<3; i++) {
00145         if ((interp = adtList->GetScalarInterpolator(drotmode, i))) {
00146             interpolator= new KX_ScalarInterpolator(&(ipocontr->GetIPOTransform().GetDeltaEulerAngles()[i]), interp);
00147             ipocontr->AddInterpolator(interpolator);
00148             ipocontr->SetIPOChannelActive(OB_DROT_X+i, true);
00149         }
00150     }
00151     for(int i=0; i<3; i++) {
00152         if ((interp = adtList->GetScalarInterpolator("scale", i))) {
00153             interpolator= new KX_ScalarInterpolator(&(ipocontr->GetIPOTransform().GetScaling()[i]), interp);
00154             ipocontr->AddInterpolator(interpolator);
00155             ipocontr->SetIPOChannelActive(OB_SIZE_X+i, true);
00156         }
00157     }
00158     for(int i=0; i<3; i++) {
00159         if ((interp = adtList->GetScalarInterpolator("delta_scale", i))) {
00160             interpolator= new KX_ScalarInterpolator(&(ipocontr->GetIPOTransform().GetDeltaScaling()[i]), interp);
00161             ipocontr->AddInterpolator(interpolator);
00162             ipocontr->SetIPOChannelActive(OB_DSIZE_X+i, true);
00163         }
00164     }
00165         
00166     {
00167         KX_ObColorIpoSGController* ipocontr_obcol=NULL;
00168             
00169         for(int i=0; i<4; i++) {
00170             if ((interp = adtList->GetScalarInterpolator("color", i))) {
00171                 if (!ipocontr_obcol) {
00172                     ipocontr_obcol = new KX_ObColorIpoSGController();
00173                     gameobj->GetSGNode()->AddSGController(ipocontr_obcol);
00174                     ipocontr_obcol->SetObject(gameobj->GetSGNode());
00175                 }
00176                 interpolator= new KX_ScalarInterpolator(&ipocontr_obcol->m_rgba[i], interp);
00177                 ipocontr_obcol->AddInterpolator(interpolator);
00178             }
00179         }
00180     }
00181 
00182     return ipocontr;
00183 }
00184 
00185 void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_BlenderSceneConverter *converter)
00186 {
00187     if (blenderobject->adt) {
00188         SG_Controller *ipocontr = BL_CreateIPO(blenderobject->adt->action, gameobj, converter);
00189         gameobj->GetSGNode()->AddSGController(ipocontr);
00190         ipocontr->SetObject(gameobj->GetSGNode());
00191     }
00192 }
00193 
00194 SG_Controller *BL_CreateLampIPO(struct bAction *action, KX_GameObject*  lightobj, KX_BlenderSceneConverter *converter)
00195 {
00196     KX_LightIpoSGController* ipocontr = new KX_LightIpoSGController();
00197 
00198     Lamp *blenderlamp = (Lamp*)lightobj->GetBlenderObject()->data;
00199 
00200     ipocontr->m_energy = blenderlamp->energy;
00201     ipocontr->m_col_rgb[0] = blenderlamp->r;
00202     ipocontr->m_col_rgb[1] = blenderlamp->g;
00203     ipocontr->m_col_rgb[2] = blenderlamp->b;
00204     ipocontr->m_dist = blenderlamp->dist;
00205 
00206     BL_InterpolatorList *adtList= GetAdtList(action, converter);
00207 
00208     // For each active channel in the adtList add an
00209     // interpolator to the game object.
00210         
00211     KX_IInterpolator *interpolator;
00212     KX_IScalarInterpolator *interp;
00213         
00214     if ((interp= adtList->GetScalarInterpolator("energy", 0))) {
00215         interpolator= new KX_ScalarInterpolator(&ipocontr->m_energy, interp);
00216         ipocontr->AddInterpolator(interpolator);
00217         ipocontr->SetModifyEnergy(true);
00218     }
00219 
00220     if ((interp = adtList->GetScalarInterpolator("distance", 0))) {
00221         interpolator= new KX_ScalarInterpolator(&ipocontr->m_dist, interp);
00222         ipocontr->AddInterpolator(interpolator);
00223         ipocontr->SetModifyDist(true);
00224     }
00225         
00226     for(int i=0; i<3; i++) {
00227         if ((interp = adtList->GetScalarInterpolator("color", i))) {
00228             interpolator= new KX_ScalarInterpolator(&ipocontr->m_col_rgb[i], interp);
00229             ipocontr->AddInterpolator(interpolator);
00230             ipocontr->SetModifyColor(true);
00231         }
00232     }
00233 
00234     return ipocontr;
00235 }
00236 
00237 void BL_ConvertLampIpos(struct Lamp* blenderlamp, KX_GameObject *lightobj,KX_BlenderSceneConverter *converter)
00238 {
00239 
00240     if (blenderlamp->adt) {
00241 
00242         SG_Controller* ipocontr = BL_CreateLampIPO(blenderlamp->adt->action, lightobj, converter);
00243         lightobj->GetSGNode()->AddSGController(ipocontr);
00244         ipocontr->SetObject(lightobj->GetSGNode());
00245         
00246         
00247     }
00248 }
00249 
00250 SG_Controller *BL_CreateCameraIPO(struct bAction *action, KX_GameObject*  cameraobj, KX_BlenderSceneConverter *converter)
00251 {
00252     KX_CameraIpoSGController* ipocontr = new KX_CameraIpoSGController();
00253 
00254     Camera *blendercamera = (Camera*)cameraobj->GetBlenderObject()->data;
00255 
00256     ipocontr->m_lens = blendercamera->lens;
00257     ipocontr->m_clipstart = blendercamera->clipsta;
00258     ipocontr->m_clipend = blendercamera->clipend;
00259 
00260     BL_InterpolatorList *adtList= GetAdtList(action, converter);
00261 
00262     // For each active channel in the adtList add an
00263     // interpolator to the game object.
00264         
00265     KX_IInterpolator *interpolator;
00266     KX_IScalarInterpolator *interp;
00267         
00268     if ((interp = adtList->GetScalarInterpolator("lens", 0))) {
00269         interpolator= new KX_ScalarInterpolator(&ipocontr->m_lens, interp);
00270         ipocontr->AddInterpolator(interpolator);
00271         ipocontr->SetModifyLens(true);
00272     }
00273 
00274     if ((interp = adtList->GetScalarInterpolator("clip_start", 0))) {
00275         interpolator= new KX_ScalarInterpolator(&ipocontr->m_clipstart, interp);
00276         ipocontr->AddInterpolator(interpolator);
00277         ipocontr->SetModifyClipStart(true);
00278     }
00279 
00280     if ((interp = adtList->GetScalarInterpolator("clip_end", 0))) {
00281         interpolator= new KX_ScalarInterpolator(&ipocontr->m_clipend, interp);
00282         ipocontr->AddInterpolator(interpolator);
00283         ipocontr->SetModifyClipEnd(true);
00284     }
00285 
00286     return ipocontr;
00287 }
00288 
00289 void BL_ConvertCameraIpos(struct Camera* blendercamera, KX_GameObject *cameraobj,KX_BlenderSceneConverter *converter)
00290 {
00291 
00292     if (blendercamera->adt) {
00293         SG_Controller* ipocontr = BL_CreateCameraIPO(blendercamera->adt->action, cameraobj, converter);
00294         cameraobj->GetSGNode()->AddSGController(ipocontr);
00295         ipocontr->SetObject(cameraobj->GetSGNode());
00296     }
00297 }
00298 
00299 
00300 void BL_ConvertWorldIpos(struct World* blenderworld,KX_BlenderSceneConverter *converter)
00301 {
00302 
00303     if (blenderworld->adt) {
00304 
00305         KX_WorldIpoController* ipocontr = new KX_WorldIpoController();
00306 
00307 // Erwin, hook up the world ipo controller here
00308 // Gino: hook it up to what ?
00309 // is there a userinterface element for that ?
00310 // for now, we have some new python hooks to access the data, for a work-around
00311         
00312         ipocontr->m_mist_start  = blenderworld->miststa;
00313         ipocontr->m_mist_dist   = blenderworld->mistdist;
00314         ipocontr->m_mist_rgb[0] = blenderworld->horr;
00315         ipocontr->m_mist_rgb[1] = blenderworld->horg;
00316         ipocontr->m_mist_rgb[2] = blenderworld->horb;
00317 
00318         BL_InterpolatorList *adtList= GetAdtList(blenderworld->adt->action, converter);
00319 
00320         // For each active channel in the adtList add an
00321         // interpolator to the game object.
00322         
00323         KX_IInterpolator *interpolator;
00324         KX_IScalarInterpolator *interp;
00325         
00326         for(int i=0; i<3; i++) {
00327             if ((interp = adtList->GetScalarInterpolator("horizon_color", i))) {
00328                 interpolator= new KX_ScalarInterpolator(&ipocontr->m_mist_rgb[i], interp);
00329                 ipocontr->AddInterpolator(interpolator);
00330                 ipocontr->SetModifyMistColor(true);
00331             }
00332         }
00333 
00334         if ((interp = adtList->GetScalarInterpolator("mist.depth", 0))) {
00335             interpolator= new KX_ScalarInterpolator(&ipocontr->m_mist_dist, interp);
00336             ipocontr->AddInterpolator(interpolator);
00337             ipocontr->SetModifyMistDist(true);
00338         }
00339 
00340         if ((interp = adtList->GetScalarInterpolator("mist.start", 0))) {
00341             interpolator= new KX_ScalarInterpolator(&ipocontr->m_mist_start, interp);
00342             ipocontr->AddInterpolator(interpolator);
00343             ipocontr->SetModifyMistStart(true);
00344         }
00345     }
00346 }
00347 
00348 static void ConvertMaterialIpos(
00349     Material* blendermaterial,
00350     dword matname_hash,
00351     KX_GameObject* gameobj,  
00352     KX_BlenderSceneConverter *converter
00353     )
00354 {
00355     if (blendermaterial->adt) {
00356         KX_MaterialIpoController* ipocontr = new KX_MaterialIpoController(matname_hash);
00357         gameobj->GetSGNode()->AddSGController(ipocontr);
00358         ipocontr->SetObject(gameobj->GetSGNode());
00359         
00360         BL_InterpolatorList *adtList= GetAdtList(blendermaterial->adt->action, converter);
00361 
00362 
00363         ipocontr->m_rgba[0] = blendermaterial->r;
00364         ipocontr->m_rgba[1] = blendermaterial->g;
00365         ipocontr->m_rgba[2] = blendermaterial->b;
00366         ipocontr->m_rgba[3] = blendermaterial->alpha;
00367 
00368         ipocontr->m_specrgb[0]  = blendermaterial->specr;
00369         ipocontr->m_specrgb[1]  = blendermaterial->specg;
00370         ipocontr->m_specrgb[2]  = blendermaterial->specb;
00371         
00372         ipocontr->m_hard        = blendermaterial->har;
00373         ipocontr->m_spec        = blendermaterial->spec;
00374         ipocontr->m_ref         = blendermaterial->ref;
00375         ipocontr->m_emit        = blendermaterial->emit;
00376         ipocontr->m_alpha       = blendermaterial->alpha;
00377         
00378         KX_IInterpolator *interpolator;
00379         KX_IScalarInterpolator *sinterp;
00380         
00381         // --
00382         for(int i=0; i<3; i++) {
00383             if ((sinterp = adtList->GetScalarInterpolator("diffuse_color", i))) {
00384                 if (!ipocontr) {
00385                     ipocontr = new KX_MaterialIpoController(matname_hash);
00386                     gameobj->GetSGNode()->AddSGController(ipocontr);
00387                     ipocontr->SetObject(gameobj->GetSGNode());
00388                 }
00389                 interpolator= new KX_ScalarInterpolator(&ipocontr->m_rgba[i], sinterp);
00390                 ipocontr->AddInterpolator(interpolator);
00391             }
00392         }
00393         
00394         if ((sinterp = adtList->GetScalarInterpolator("alpha", 0))) {
00395             if (!ipocontr) {
00396                 ipocontr = new KX_MaterialIpoController(matname_hash);
00397                 gameobj->GetSGNode()->AddSGController(ipocontr);
00398                 ipocontr->SetObject(gameobj->GetSGNode());
00399             }
00400             interpolator= new KX_ScalarInterpolator(&ipocontr->m_rgba[3], sinterp);
00401             ipocontr->AddInterpolator(interpolator);
00402         }
00403 
00404         for(int i=0; i<3; i++) {
00405             if ((sinterp = adtList->GetScalarInterpolator("specular_color", i))) {
00406                 if (!ipocontr) {
00407                     ipocontr = new KX_MaterialIpoController(matname_hash);
00408                     gameobj->GetSGNode()->AddSGController(ipocontr);
00409                     ipocontr->SetObject(gameobj->GetSGNode());
00410                 }
00411                 interpolator= new KX_ScalarInterpolator(&ipocontr->m_specrgb[i], sinterp);
00412                 ipocontr->AddInterpolator(interpolator);
00413             }
00414         }
00415         
00416         if ((sinterp = adtList->GetScalarInterpolator("specular_hardness", 0))) {
00417             if (!ipocontr) {
00418                 ipocontr = new KX_MaterialIpoController(matname_hash);
00419                 gameobj->GetSGNode()->AddSGController(ipocontr);
00420                 ipocontr->SetObject(gameobj->GetSGNode());
00421             }
00422             interpolator= new KX_ScalarInterpolator(&ipocontr->m_hard, sinterp);
00423             ipocontr->AddInterpolator(interpolator);
00424         }
00425 
00426         if ((sinterp = adtList->GetScalarInterpolator("specularity", 0))) {
00427             if (!ipocontr) {
00428                 ipocontr = new KX_MaterialIpoController(matname_hash);
00429                 gameobj->GetSGNode()->AddSGController(ipocontr);
00430                 ipocontr->SetObject(gameobj->GetSGNode());
00431             }
00432             interpolator= new KX_ScalarInterpolator(&ipocontr->m_spec, sinterp);
00433             ipocontr->AddInterpolator(interpolator);
00434         }
00435         
00436         if ((sinterp = adtList->GetScalarInterpolator("diffuse_reflection", 0))) {
00437             if (!ipocontr) {
00438                 ipocontr = new KX_MaterialIpoController(matname_hash);
00439                 gameobj->GetSGNode()->AddSGController(ipocontr);
00440                 ipocontr->SetObject(gameobj->GetSGNode());
00441             }
00442             interpolator= new KX_ScalarInterpolator(&ipocontr->m_ref, sinterp);
00443             ipocontr->AddInterpolator(interpolator);
00444         }   
00445         
00446         if ((sinterp = adtList->GetScalarInterpolator("emit", 0))) {
00447             if (!ipocontr) {
00448                 ipocontr = new KX_MaterialIpoController(matname_hash);
00449                 gameobj->GetSGNode()->AddSGController(ipocontr);
00450                 ipocontr->SetObject(gameobj->GetSGNode());
00451             }
00452             interpolator= new KX_ScalarInterpolator(&ipocontr->m_emit, sinterp);
00453             ipocontr->AddInterpolator(interpolator);
00454         }
00455     }       
00456 }
00457 
00458 void BL_ConvertMaterialIpos(
00459     struct Object* blenderobject,
00460     KX_GameObject* gameobj,  
00461     KX_BlenderSceneConverter *converter
00462     )
00463 {
00464     if (blenderobject->totcol==1)
00465     {
00466         Material *mat = give_current_material(blenderobject, 1);
00467         // if there is only one material attached to the mesh then set material_index in BL_ConvertMaterialIpos to NULL
00468         // --> this makes the UpdateMaterialData function in KX_GameObject.cpp use the old hack of using SetObjectColor
00469         // because this yields a better performance as not all the vertex colors need to be edited
00470         if(mat) ConvertMaterialIpos(mat, 0, gameobj, converter);
00471     }
00472     else
00473     {
00474         for (int material_index=1; material_index <= blenderobject->totcol; material_index++)
00475         {
00476             Material *mat = give_current_material(blenderobject, material_index);
00477             STR_HashedString matname;
00478             if(mat) {
00479                 matname= mat->id.name; // who is using this name? can we remove the MA here?
00480                 ConvertMaterialIpos(mat, matname.hash(), gameobj, converter);
00481             }
00482         }
00483     }
00484 }
00485