00001
00007 #include "SO3Material.h"
00008 #include "SO3Texture.h"
00009 #include "../SO3SceneGraph/SO3Scene.h"
00010 #include "../SO3Utils/SO3ConversionTools.h"
00011
00012 namespace SO3
00013 {
00014
00015 SMaterial::SMaterial(SScene* scene, std::string groupname, std::string materialName) : SData(materialName)
00016 {
00017 O3MaterialPtr.setNull();
00018 associatedWidget = 0;
00019 mScene = scene;
00020 mGroupName = groupname;
00021
00022
00023 O3MaterialPtr = (mScene->O3MaterialManager->getByName(materialName, groupname));
00024
00025
00026 if (materialName == std::string("BaseWhite"))
00027 O3MaterialPtr = O3MaterialPtr.get()->clone(materialName, true, groupname);
00028
00029
00030 if (O3MaterialPtr.isNull())
00031 {
00032 O3MaterialPtr = Ogre::MaterialManager::getSingleton().create(materialName, mGroupName);
00033 O3MaterialPtr->getTechnique(0)->getPass(0)->createTextureUnitState();
00034 }
00035 }
00036
00037 SMaterial::SMaterial() : SData("")
00038 {
00039
00040 }
00041
00042 SMaterial::~SMaterial()
00043 {
00044
00045 if((O3MaterialPtr->getGroup() != Ogre::ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME) && (O3MaterialPtr->getGroup() == mGroupName))
00046 Ogre::MaterialManager::getSingleton().remove(O3MaterialPtr->getHandle());
00047 }
00048
00049 Ogre::MaterialPtr SMaterial::getOgreMaterialPointer()
00050 {
00051 return this->O3MaterialPtr;
00052 }
00053
00054 SScene* SMaterial::GetScene()
00055 {
00056 return mScene;
00057 }
00058
00059 std::string SMaterial::GetGroupName()
00060 {
00061 return mGroupName;
00062 }
00063
00064 int SMaterial::GetNumTechniques()
00065 {
00066 assert(!O3MaterialPtr.isNull());
00067
00068 return O3MaterialPtr->getNumTechniques();
00069 }
00070
00071 int SMaterial::GetNumPasses(unsigned int technique)
00072 {
00073 assert(!O3MaterialPtr.isNull());
00074 int returnValue = 0;
00075
00076 if (technique >= O3MaterialPtr->getNumTechniques())
00077 return returnValue;
00078
00079 Ogre::Technique* tmpTechnique = O3MaterialPtr->getTechnique(technique);
00080 if(tmpTechnique != 0)
00081 returnValue = tmpTechnique->getNumPasses();
00082
00083 return returnValue;
00084 }
00085
00086 int SMaterial::GetNumTextureUnitStates(unsigned int technique, unsigned int pass)
00087 {
00088 assert(!O3MaterialPtr.isNull());
00089 int returnValue = 0;
00090
00091 if (technique >= O3MaterialPtr->getNumTechniques())
00092 return returnValue;
00093
00094 Ogre::Pass* tmpPass = GetMaterialPass(technique, pass);
00095 if(tmpPass != 0)
00096 returnValue = tmpPass->getNumTextureUnitStates();
00097
00098 return returnValue;
00099 }
00100
00101 Ogre::TextureUnitState* SMaterial::GetMaterialUnitState(unsigned int technique, unsigned int pass, unsigned int textureUnit)
00102 {
00103 assert(!O3MaterialPtr.isNull());
00104
00105
00106 Ogre::TextureUnitState* returnValue = 0;
00107
00108 if (technique >= O3MaterialPtr->getNumTechniques())
00109 return returnValue;
00110
00111 Ogre::Technique* tmpTechnique = O3MaterialPtr->getTechnique(technique);
00112 if(tmpTechnique != 0)
00113 {
00114 Ogre::Pass* tmpPass = 0;
00115 if (pass < tmpTechnique->getNumPasses())
00116 tmpPass = tmpTechnique->getPass(pass);
00117
00118 if (tmpPass != 0)
00119 {
00120 unsigned int numTextureUnits = tmpPass->getNumTextureUnitStates();
00121 if ((numTextureUnits > 0) && (textureUnit < numTextureUnits))
00122 {
00123 returnValue = tmpPass->getTextureUnitState(textureUnit);
00124 }
00125 }
00126 }
00127 return returnValue;
00128 }
00129
00130 Ogre::Pass* SMaterial::GetMaterialPass(unsigned int technique, unsigned int pass)
00131 {
00132 assert(!O3MaterialPtr.isNull());
00133
00134
00135 Ogre::Pass* returnValue = 0;
00136
00137 if (technique >= O3MaterialPtr->getNumTechniques())
00138 return returnValue;
00139
00140 Ogre::Technique* tmpTechnique = O3MaterialPtr->getTechnique(technique);
00141 if(tmpTechnique != 0)
00142 {
00143 if (pass < tmpTechnique->getNumPasses())
00144 returnValue = tmpTechnique->getPass(pass);
00145 }
00146 return returnValue;
00147 }
00148
00149 std::string SMaterial::GetTechniqueName(unsigned int technique)
00150 {
00151 assert(!O3MaterialPtr.isNull());
00152
00153 std::string returnValue("");
00154
00155 if (technique >= O3MaterialPtr->getNumTechniques())
00156 return returnValue;
00157
00158 Ogre::Technique* tmpTechnique = O3MaterialPtr->getTechnique(technique);
00159 if(tmpTechnique != 0)
00160 {
00161 returnValue = tmpTechnique->getName();
00162 if(returnValue.empty())
00163 returnValue = boost::str(boost::format("%1%") %technique);
00164 }
00165
00166 return returnValue;
00167 }
00168
00169 int SMaterial::GetTechniqueIndexByName(std::string techname)
00170 {
00171 assert(!O3MaterialPtr.isNull());
00172
00173 bool found = false;
00174 int index = -1;
00175 int numTech = GetNumTechniques();
00176 int p = 0;
00177
00178 while(!found && p<numTech)
00179 {
00180 Ogre::Technique* myTec = O3MaterialPtr->getTechnique(p);
00181 if (myTec != 0)
00182 {
00183 if(myTec->getName() == techname)
00184 {
00185 index = p;
00186 found = true;
00187 }
00188 }
00189 p++;
00190 }
00191
00192 return index;
00193 }
00194
00195 std::string SMaterial::GetPassName(unsigned int technique, unsigned int pass)
00196 {
00197 assert(!O3MaterialPtr.isNull());
00198
00199 std::string returnValue("");
00200
00201 Ogre::Pass* tmpPass = GetMaterialPass(technique, pass);
00202 if(tmpPass != 0)
00203 {
00204 returnValue = tmpPass->getName();
00205 if(returnValue.empty())
00206 returnValue = boost::str(boost::format("%1%") %pass);
00207 }
00208
00209 return returnValue;
00210 }
00211
00212 int SMaterial::GetPassIndexByName(unsigned int technique, std::string passname)
00213 {
00214 assert(!O3MaterialPtr.isNull());
00215
00216 bool found = false;
00217 int index = -1;
00218
00219 if (technique >= O3MaterialPtr->getNumTechniques())
00220 return index;
00221
00222 Ogre::Technique* tmpTechnique = O3MaterialPtr->getTechnique(technique);
00223 if(tmpTechnique != 0)
00224 {
00225 int numPass = tmpTechnique->getNumPasses();
00226 int p = 0;
00227
00228 while(!found && p<numPass)
00229 {
00230 Ogre::Pass* myPass = tmpTechnique->getPass(p);
00231 if (myPass != 0)
00232 {
00233 if(myPass->getName() == passname)
00234 {
00235 index = p;
00236 found = true;
00237 }
00238 }
00239 p++;
00240 }
00241 }
00242
00243 return index;
00244 }
00245
00246
00247 std::string SMaterial::GetTextureUnitName(unsigned int technique, unsigned int pass, unsigned int textureUnit)
00248 {
00249 assert(!O3MaterialPtr.isNull());
00250
00251 std::string returnValue("");
00252 Ogre::TextureUnitState* tmpTex = GetMaterialUnitState(technique, pass, textureUnit);
00253 if(tmpTex != 0)
00254 {
00255 returnValue = tmpTex->getName();
00256 if(returnValue.empty())
00257 returnValue = boost::str(boost::format("%1%") %textureUnit);
00258 }
00259
00260 return returnValue;
00261 }
00262
00263 int SMaterial::GetTextureUnitIndexByName(unsigned int technique, unsigned int pass, std::string texname)
00264 {
00265 assert(!O3MaterialPtr.isNull());
00266
00267 int index = -1;
00268
00269 Ogre::Pass* tmpPass = GetMaterialPass(technique, pass);
00270 if(tmpPass != 0)
00271 index = tmpPass->getTextureUnitStateIndex(tmpPass->getTextureUnitState(texname));
00272
00273 return index;
00274 }
00275
00276 std::string SMaterial::GetTextureName(unsigned int technique, unsigned int pass, unsigned int textureUnit)
00277 {
00278 assert(!O3MaterialPtr.isNull());
00279
00280 std::string texname;
00281 Ogre::TextureUnitState* tmpTextureUnit = GetMaterialUnitState(technique, pass, textureUnit);
00282 if (tmpTextureUnit != 0)
00283 texname = tmpTextureUnit->getTextureName();
00284
00285 return texname;
00286 }
00287
00288
00289 void SMaterial::SetTextureUScroll(unsigned int technique, unsigned int pass, unsigned int textureUnit, float value)
00290 {
00291 Ogre::TextureUnitState* tmpTextureUnit = GetMaterialUnitState(technique, pass, textureUnit);
00292 if(tmpTextureUnit != 0)
00293 tmpTextureUnit->setTextureUScroll(Ogre::Real(value));
00294 else
00295 OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, "Texture unit not found on material.", "SMaterial::SetTextureUScroll");
00296 }
00297
00298 float SMaterial::GetTextureUScroll(unsigned int technique, unsigned int pass, unsigned int textureUnit)
00299 {
00300 Ogre::TextureUnitState* tmpTextureUnit = GetMaterialUnitState(technique, pass, textureUnit);
00301 if(tmpTextureUnit != 0)
00302 return static_cast <float> (tmpTextureUnit->getTextureUScroll());
00303 else
00304 OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, "Texture unit not found on material.", "SMaterial::GetTextureUScroll");
00305
00306 return 0.0f;
00307 }
00308
00309 void SMaterial::SetTextureVScroll(unsigned int technique, unsigned int pass, unsigned int textureUnit, float value)
00310 {
00311 Ogre::TextureUnitState* tmpTextureUnit = GetMaterialUnitState(technique, pass, textureUnit);
00312 if(tmpTextureUnit != 0)
00313 tmpTextureUnit->setTextureVScroll(Ogre::Real(value));
00314 else
00315 OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, "Texture unit not found on material.", "SMaterial::SetTextureVScroll");
00316 }
00317
00318 float SMaterial::GetTextureVScroll(unsigned int technique, unsigned int pass, unsigned int textureUnit)
00319 {
00320 Ogre::TextureUnitState* tmpTextureUnit = GetMaterialUnitState(technique, pass, textureUnit);
00321 if(tmpTextureUnit != 0)
00322 return static_cast <float> (tmpTextureUnit->getTextureVScroll());
00323 else
00324 OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, "Texture unit not found on material.", "SMaterial::GetTextureVScroll");
00325
00326 return 0.0f;
00327 }
00328
00329 void SMaterial::SetTextureUScale(unsigned int technique, unsigned int pass, unsigned int textureUnit, float value)
00330 {
00331 Ogre::TextureUnitState* tmpTextureUnit = GetMaterialUnitState(technique, pass, textureUnit);
00332 if(tmpTextureUnit != 0)
00333 tmpTextureUnit->setTextureUScale(Ogre::Real(value));
00334 else
00335 OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, "Texture unit not found on material.", "SMaterial::SetTextureUScale");
00336 }
00337
00338 float SMaterial::GetTextureUScale(unsigned int technique, unsigned int pass, unsigned int textureUnit)
00339 {
00340 Ogre::TextureUnitState* tmpTextureUnit = GetMaterialUnitState(technique, pass, textureUnit);
00341 if(tmpTextureUnit != 0)
00342 return static_cast <float> (tmpTextureUnit->getTextureUScale());
00343 else
00344 OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, "Texture unit not found on material.", "SMaterial::GetTextureUScale");
00345
00346 return 0.0f;
00347 }
00348
00349 void SMaterial::SetTextureVScale(unsigned int technique, unsigned int pass, unsigned int textureUnit, float value)
00350 {
00351 Ogre::TextureUnitState* tmpTextureUnit = GetMaterialUnitState(technique, pass, textureUnit);
00352 if(tmpTextureUnit != 0)
00353 tmpTextureUnit->setTextureVScale(Ogre::Real(value));
00354 else
00355 OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, "Texture unit not found on material.", "SMaterial::SetTextureVScale");
00356 }
00357
00358 float SMaterial::GetTextureVScale(unsigned int technique, unsigned int pass, unsigned int textureUnit)
00359 {
00360 Ogre::TextureUnitState* tmpTextureUnit = GetMaterialUnitState(technique, pass, textureUnit);
00361 if(tmpTextureUnit != 0)
00362 return static_cast <float> (tmpTextureUnit->getTextureVScale());
00363 else
00364 OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, "Texture unit not found on material.", "SMaterial::GetTextureVScale");
00365
00366 return 0.0f;
00367 }
00368
00369 void SMaterial::SetTextureRotate(unsigned int technique, unsigned int pass, unsigned int textureUnit, const float &radianAngle)
00370 {
00371 Ogre::TextureUnitState* tmpTextureUnit = GetMaterialUnitState(technique, pass, textureUnit);
00372 if(tmpTextureUnit != 0)
00373 tmpTextureUnit->setTextureRotate(Ogre::Radian(radianAngle));
00374 else
00375 OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, "Texture unit not found on material.", "SMaterial::SetTextureRotate");
00376 }
00377
00378 const float SMaterial::GetTextureRotate(unsigned int technique, unsigned int pass, unsigned int textureUnit)
00379 {
00380 Ogre::TextureUnitState* tmpTextureUnit = GetMaterialUnitState(technique, pass, textureUnit);
00381 if(tmpTextureUnit != 0)
00382 return static_cast <float> (tmpTextureUnit->getTextureRotate().valueRadians());
00383 else
00384 OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, "Texture unit not found on material.", "SMaterial::GetTextureRotate");
00385
00386 return 0.0f;
00387 }
00388
00389 void SMaterial::SetTextureScrollAnimation(unsigned int technique, unsigned int pass, unsigned int textureUnit, float uSpeed, float vSpeed)
00390 {
00391 Ogre::TextureUnitState* tmpTextureUnit = GetMaterialUnitState(technique, pass, textureUnit);
00392 if(tmpTextureUnit != 0)
00393 tmpTextureUnit->setScrollAnimation(Ogre::Real(uSpeed), Ogre::Real(vSpeed));
00394 else
00395 OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, "Texture unit not found on material.", "SMaterial::SetScrollAnimation");
00396 }
00397
00398 void SMaterial::SetTextureRotateAnimation(unsigned int technique, unsigned int pass, unsigned int textureUnit, float speed)
00399 {
00400 Ogre::TextureUnitState* tmpTextureUnit = GetMaterialUnitState(technique, pass, textureUnit);
00401 if(tmpTextureUnit != 0)
00402 tmpTextureUnit->setRotateAnimation(Ogre::Real(speed));
00403 else
00404 OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, "Texture unit not found on material.", "SMaterial::SetRotateAnimation");
00405 }
00406
00407 SWidget* SMaterial::GetAssociatedWidget()
00408 {
00409 return associatedWidget;
00410 }
00411
00412 void SMaterial::SetAssociatedWidget(SWidget* newAssociatedWidget)
00413 {
00414
00415 if((associatedWidget != 0) && (newAssociatedWidget != 0))
00416 OGRE_EXCEPT(Ogre::Exception::ERR_INTERNAL_ERROR, "Cannot set widget on material: This material is already associated to a widget instance!", "SMaterial::SetAssociatedWidget");
00417
00418 associatedWidget = newAssociatedWidget;
00419 }
00420
00421 bool SMaterial::GetReceiveShadows()
00422 {
00423 assert(!O3MaterialPtr.isNull());
00424
00425 return O3MaterialPtr->getReceiveShadows();
00426 }
00427
00428 void SMaterial::SetReceiveShadows(bool state)
00429 {
00430 assert(!O3MaterialPtr.isNull());
00431
00432 O3MaterialPtr->setReceiveShadows(state);
00433 }
00434
00435 bool SMaterial::GetLightingEnabled(unsigned int tech, unsigned int pass)
00436 {
00437 assert(!O3MaterialPtr.isNull());
00438 Ogre::Pass* opass = GetMaterialPass(tech, pass);
00439 if (opass != 0)
00440 return opass->getLightingEnabled();
00441 else
00442 return false;
00443 }
00444
00445 void SMaterial::SetLightingEnabled(unsigned int tech, unsigned int pass, bool state)
00446 {
00447 assert(!O3MaterialPtr.isNull());
00448
00449 Ogre::Pass* opass = GetMaterialPass(tech, pass);
00450 if (opass != 0)
00451 opass->setLightingEnabled(state);
00452 }
00453
00454 void SMaterial::SetLightingEnabled(bool state)
00455 {
00456 assert(!O3MaterialPtr.isNull());
00457
00458 O3MaterialPtr->setLightingEnabled(state);
00459 }
00460
00461 void SMaterial::SetAmbientColor(int color)
00462 {
00463 assert(!O3MaterialPtr.isNull());
00464
00465 O3MaterialPtr->setAmbient(ConversionTools::ScolToOgreColorRGBA(color));
00466 }
00467
00468 void SMaterial::SetAmbientColor(unsigned int tech, unsigned int pass, int color)
00469 {
00470 assert(!O3MaterialPtr.isNull());
00471 Ogre::Pass* opass = GetMaterialPass(tech, pass);
00472 if (opass != 0)
00473 opass->setAmbient(ConversionTools::ScolToOgreColorRGBA(color));
00474 }
00475
00476 int SMaterial::GetAmbientColor(unsigned int tech, unsigned int pass)
00477 {
00478 int retColor = 0;
00479 assert(!O3MaterialPtr.isNull());
00480 Ogre::Pass* opass = GetMaterialPass(tech, pass);
00481 if (opass != 0)
00482 retColor = ConversionTools::OgreToScolColorRGBA(opass->getAmbient());
00483
00484 return retColor;
00485 }
00486
00487 void SMaterial::SetDiffuseColor(int color)
00488 {
00489 assert(!O3MaterialPtr.isNull());
00490
00491 O3MaterialPtr->setDiffuse(ConversionTools::ScolToOgreColorRGBA(color));
00492 }
00493
00494 void SMaterial::SetDiffuseColor(unsigned int tech, unsigned int pass, int color)
00495 {
00496 assert(!O3MaterialPtr.isNull());
00497 Ogre::Pass* opass = GetMaterialPass(tech, pass);
00498 if (opass != 0)
00499 opass->setDiffuse(ConversionTools::ScolToOgreColorRGBA(color));
00500 }
00501
00502 int SMaterial::GetDiffuseColor(unsigned int tech, unsigned int pass)
00503 {
00504 int retColor = 0;
00505 assert(!O3MaterialPtr.isNull());
00506 Ogre::Pass* opass = GetMaterialPass(tech, pass);
00507 if (opass != 0)
00508 retColor = ConversionTools::OgreToScolColorRGBA(opass->getDiffuse());
00509
00510 return retColor;
00511 }
00512
00513 void SMaterial::SetSpecularColor(int color)
00514 {
00515 assert(!O3MaterialPtr.isNull());
00516
00517 O3MaterialPtr->setSpecular(ConversionTools::ScolToOgreColorRGBA(color));
00518 }
00519
00520 void SMaterial::SetSpecularColor(unsigned int tech, unsigned int pass, int color)
00521 {
00522 assert(!O3MaterialPtr.isNull());
00523 Ogre::Pass* opass = GetMaterialPass(tech, pass);
00524 if (opass != 0)
00525 opass->setSpecular(ConversionTools::ScolToOgreColorRGBA(color));
00526 }
00527
00528 int SMaterial::GetSpecularColor(unsigned int tech, unsigned int pass)
00529 {
00530 int retColor = 0;
00531 assert(!O3MaterialPtr.isNull());
00532 Ogre::Pass* opass = GetMaterialPass(tech, pass);
00533 if (opass != 0)
00534 retColor = ConversionTools::OgreToScolColorRGBA(opass->getSpecular());
00535
00536 return retColor;
00537 }
00538
00539 void SMaterial::SetSelfIlluminationColor(int color)
00540 {
00541 assert(!O3MaterialPtr.isNull());
00542
00543 O3MaterialPtr->setSelfIllumination(ConversionTools::ScolToOgreColorRGBA(color));
00544 }
00545
00546 void SMaterial::SetSelfIlluminationColor(unsigned int tech, unsigned int pass, int color)
00547 {
00548 assert(!O3MaterialPtr.isNull());
00549 Ogre::Pass* opass = GetMaterialPass(tech, pass);
00550 if (opass != 0)
00551 opass->setSelfIllumination(ConversionTools::ScolToOgreColorRGBA(color));
00552 }
00553
00554 int SMaterial::GetSelfIlluminationColor(unsigned int tech, unsigned int pass)
00555 {
00556 int retColor = 0;
00557 assert(!O3MaterialPtr.isNull());
00558 Ogre::Pass* opass = GetMaterialPass(tech, pass);
00559 if (opass != 0)
00560 retColor = ConversionTools::OgreToScolColorRGBA(opass->getSelfIllumination());
00561
00562 return retColor;
00563 }
00564
00565 void SMaterial::SetShininess(float value)
00566 {
00567 assert(!O3MaterialPtr.isNull());
00568
00569 O3MaterialPtr->setShininess(value);
00570 }
00571
00572 void SMaterial::SetShininess(unsigned int tech, unsigned int pass, float value)
00573 {
00574 assert(!O3MaterialPtr.isNull());
00575 Ogre::Pass* opass = GetMaterialPass(tech, pass);
00576 if (opass != 0)
00577 opass->setShininess(value);
00578 }
00579
00580 float SMaterial::GetShininess(unsigned int tech, unsigned int pass)
00581 {
00582 float ret = 0;
00583 assert(!O3MaterialPtr.isNull());
00584 Ogre::Pass* opass = GetMaterialPass(tech, pass);
00585 if (opass != 0)
00586 ret = opass->getShininess();
00587
00588 return ret;
00589 }
00590
00591 void SMaterial::SetTexture(unsigned int tech, unsigned int pass, unsigned int textureUnit, STexture* texture)
00592 {
00593 assert(!O3MaterialPtr.isNull());
00594 Ogre::TextureUnitState* tmpTextureUnit = GetMaterialUnitState(tech, pass, textureUnit);
00595 if (tmpTextureUnit !=0)
00596 {
00597 tmpTextureUnit->setTextureName(texture->GetName());
00598 tmpTextureUnit->retryTextureLoad();
00599 }
00600 }
00601
00602 STexture* SMaterial::GetTexture(unsigned int tech, unsigned int pass, unsigned int textureUnit)
00603 {
00604 assert(!O3MaterialPtr.isNull());
00605 std::string texname = GetTextureName(tech, pass, textureUnit);
00606
00607 if (texname.empty())
00608 return 0;
00609
00610 STexture* newTex = mScene->GetTexture(mGroupName, texname);
00611 if (newTex == 0)
00612 newTex = mScene->CreateTexture(mGroupName, texname, std::string(""));
00613
00614 return newTex;
00615 }
00616
00617 }