Blender V2.61 - r43446
|
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