|
Blender
V2.59
|
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