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