diff --git a/include/gz/sim/InstallationDirectories.hh b/include/gz/sim/InstallationDirectories.hh index 08e3b2b29e..a34478376b 100644 --- a/include/gz/sim/InstallationDirectories.hh +++ b/include/gz/sim/InstallationDirectories.hh @@ -50,6 +50,9 @@ namespace gz /// \brief getWorldInstallDir return the world install dir GZ_SIM_VISIBLE std::string getWorldInstallDir(); + + /// \brief getMediaInstallDir return the media install dir + GZ_SIM_VISIBLE std::string getMediaInstallDir(); } } } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8466679071..af621745a7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -46,6 +46,11 @@ set(cli_sources cmd/ModelCommandAPI.cc ) +set(material_sources + rendering/MaterialParser/MaterialParser.cc + rendering/MaterialParser/ConfigLoader.cc +) + set (sources Actor.cc Barrier.cc @@ -78,6 +83,7 @@ set (sources ${network_sources} ${comms_sources} ${component_sources} + ${material_sources} ) set (gtest_sources @@ -186,7 +192,9 @@ set_property( GZ_SIM_PLUGIN_RELATIVE_INSTALL_DIR="${GZ_LIB_INSTALL_DIR}/gz-${GZ_DESIGNATION}-${PROJECT_VERSION_MAJOR}/plugins" GZ_SIM_GUI_PLUGIN_RELATIVE_INSTALL_DIR="${GZ_LIB_INSTALL_DIR}/gz-${GZ_DESIGNATION}-${PROJECT_VERSION_MAJOR}/plugins/gui" GZ_SIM_WORLD_RELATIVE_INSTALL_DIR="${GZ_DATA_INSTALL_DIR}/worlds" + GZ_SIM_MEDIA_RELATIVE_INSTALL_DIR="${GZ_DATA_INSTALL_DIR}/media" ) +install(FILES "rendering/MaterialParser/gazebo.material" DESTINATION ${GZ_DATA_INSTALL_DIR}/media) target_link_libraries(${PROJECT_LIBRARY_TARGET_NAME} PUBLIC diff --git a/src/InstallationDirectories.cc b/src/InstallationDirectories.cc index 2aa64e334d..f7b22f7cf6 100644 --- a/src/InstallationDirectories.cc +++ b/src/InstallationDirectories.cc @@ -62,6 +62,12 @@ std::string getWorldInstallDir() getInstallPrefix(), GZ_SIM_WORLD_RELATIVE_INSTALL_DIR); } +std::string getMediaInstallDir() +{ + return gz::common::joinPaths( + getInstallPrefix(), GZ_SIM_MEDIA_RELATIVE_INSTALL_DIR); +} + } } } diff --git a/src/SdfEntityCreator.cc b/src/SdfEntityCreator.cc index fba9663f3e..0117768c83 100644 --- a/src/SdfEntityCreator.cc +++ b/src/SdfEntityCreator.cc @@ -95,6 +95,8 @@ #include "gz/sim/components/World.hh" #endif +#include "rendering/MaterialParser/MaterialParser.hh" + class gz::sim::SdfEntityCreatorPrivate { /// \brief Pointer to entity component manager. We don't assume ownership. @@ -114,6 +116,9 @@ class gz::sim::SdfEntityCreatorPrivate /// \brief Keep track of new visuals being added, so we load their plugins /// only after we have their scoped name. public: std::map newVisuals; + + /// \brief Parse Gazebo defined materials for visuals + public: MaterialParser materialParser; }; using namespace gz; @@ -204,6 +209,7 @@ SdfEntityCreator::SdfEntityCreator(EntityComponentManager &_ecm, { this->dataPtr->ecm = &_ecm; this->dataPtr->eventManager = &_eventManager; + this->dataPtr->materialParser.Load(); } ///////////////////////////////////////////////// @@ -834,8 +840,47 @@ Entity SdfEntityCreator::CreateEntities(const sdf::Visual *_visual) // \todo(louise) Populate with default material if undefined if (_visual->Material()) { + sdf::Material visualMaterial = *_visual->Material(); + if (!_visual->Material()->ScriptUri().empty()) + { + gzwarn << "Gazebo does not support Ogre material scripts. See " << + "https://gazebosim.org/api/sim/8/migrationsdf.html#:~:text=Materials " << + "for details." << std::endl; + std::string scriptUri = visualMaterial.ScriptUri(); + if (scriptUri != "file://media/materials/scripts/gazebo.material") { + gzwarn << "Custom material scripts are not supported." + << std::endl; + } + } + if (!_visual->Material()->ScriptName().empty()) + { + std::string scriptName = visualMaterial.ScriptName(); + + if ((scriptName.find("Gazebo/") == 0u)) + { + gzwarn << "Using an internal gazebo.material to parse " + << scriptName << std::endl; + std::optional parsed = + this->dataPtr->materialParser.GetMaterialValues(scriptName); + + if(parsed.has_value()) + { + visualMaterial.SetAmbient + (parsed->ambient.value_or(visualMaterial.Ambient())); + visualMaterial.SetDiffuse + (parsed->diffuse.value_or(visualMaterial.Diffuse())); + visualMaterial.SetSpecular + (parsed->specular.value_or(visualMaterial.Specular())); + } + else + { + gzwarn << "Material " << scriptName << + " not recognized or supported, using default." << std::endl; + } + } + } this->dataPtr->ecm->CreateComponent(visualEntity, - components::Material(*_visual->Material())); + components::Material(visualMaterial)); } // store the plugin in a component diff --git a/src/rendering/MaterialParser/ConfigLoader.cc b/src/rendering/MaterialParser/ConfigLoader.cc new file mode 100644 index 0000000000..8f702749f0 --- /dev/null +++ b/src/rendering/MaterialParser/ConfigLoader.cc @@ -0,0 +1,498 @@ +/* + * Copyright (C) 2023 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +// This code is adapted from https://wiki.ogre3d.org/All-purpose+script+parser + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "gz/sim/InstallationDirectories.hh" + +#include "ConfigLoader.hh" + +using namespace gz; +using namespace sim; + +void ConfigLoader::LoadMaterialFiles(ConfigLoader * _c) +{ + try + { + std::string installedConfig = common::joinPaths( + gz::sim::getMediaInstallDir(), + "gazebo.material"); + std::ifstream in(installedConfig, std::ios::binary); + _c->ParseScript(in); + } + catch(std::filesystem::filesystem_error & e) + { + gzerr << e.what() << std::endl; + } +} + +ConfigLoader::ConfigLoader() +{ +} + +ConfigLoader::~ConfigLoader() +{ + clearScriptList(); +} + +void ConfigLoader::clearScriptList() +{ + for (auto & i : mScriptList) + { + delete i.second; + } + mScriptList.clear(); +} + +ConfigNode * ConfigLoader::GetConfigScript(const std::string & _name) +{ + auto i = mScriptList.find(_name); + // If found.. + if (i != mScriptList.end()) + { + return i->second; + } + else + { + return nullptr; + } +} + +std::map ConfigLoader::GetAllConfigScripts() +{ + return mScriptList; +} + +void ConfigLoader::ParseScript(std::ifstream & _stream) +{ + // Get first token + nextToken(_stream); + if (tok == TOKEN_EOF) + { + _stream.close(); + return; + } + + // Parse the script + parseNodes(_stream, 0); + + _stream.close(); +} + +void ConfigLoader::nextToken(std::ifstream & stream) +{ + lastTok = tok; + lastTokVal = tokVal; + + // EOF token + if (stream.eof()) + { + tok = TOKEN_EOF; + return; + } + + // Get next character + int ch = stream.get(); + if (ch == -1) + { + tok = TOKEN_EOF; + return; + } + // Skip leading spaces / tabs + while ((ch == ' ' || ch == 9) && !stream.eof()) + { + ch = stream.get(); + } + + if (stream.eof()) + { + tok = TOKEN_EOF; + return; + } + + // Newline token + if (ch == '\r' || ch == '\n') + { + do + { + ch = stream.get(); + } while ((ch == '\r' || ch == '\n') && !stream.eof()); + + stream.unget(); + + tok = TOKEN_NewLine; + return; + } + else if (ch == '{') + { + // Open brace token + tok = TOKEN_OpenBrace; + return; + } + else if (ch == '}') + { + // Close brace token + tok = TOKEN_CloseBrace; + return; + } + + // Text token + if (ch < 32 || ch > 122) + { // Verify valid char + throw std::runtime_error( + "Parse Error: Invalid character, ConfigLoader::load()"); + } + + tokVal = ""; + tok = TOKEN_Text; + do + { + // Skip comments + if (ch == '/') + { + int ch2 = stream.peek(); + + // C++ style comment (//) + if (ch2 == '/') + { + stream.get(); + do + { + ch = stream.get(); + } while (ch != '\r' && ch != '\n' && !stream.eof()); + + tok = TOKEN_NewLine; + return; + } + else if (ch2 == '*') + { + stream.get(); + do + { + ch = stream.get(); + ch2 = stream.peek(); + } while (!(ch == '*' && ch2 == '/') && !stream.eof()); + stream.get(); + + do + { + ch = stream.get(); + } while (ch != '\r' && ch != '\n' && !stream.eof()); + continue; + } + } + + // Add valid char to tokVal + tokVal += static_cast(ch); + + // Next char + ch = stream.get(); + } while (ch > 32 && ch <= 122 && !stream.eof()); + + stream.unget(); + + return; +} + +void ConfigLoader::skipNewLines(std::ifstream & stream) +{ + while (tok == TOKEN_NewLine) + { + nextToken(stream); + } +} + +void ConfigLoader::parseNodes(std::ifstream & stream, ConfigNode * parent) +{ + typedef std::pair < std::string, ConfigNode * > ScriptItem; + + while (true) + { + switch (tok) + { + // Node + case TOKEN_Text: + // Add the new node + ConfigNode * newNode; + if (parent) + { + newNode = parent->AddChild(tokVal); + } + else + { + newNode = new ConfigNode(0, tokVal); + } + + // Get values + nextToken(stream); + while (tok == TOKEN_Text) + { + newNode->AddValue(tokVal); + nextToken(stream); + } + + // Add root nodes to scriptList + if (!parent) + { + std::string key; + + if (newNode->GetValues().empty()) + { + key = newNode->GetName() + ' '; + } + else + { + key = newNode->GetName() + ' ' + newNode->GetValues().front(); + } + + mScriptList.insert(ScriptItem(key, newNode)); + } + + skipNewLines(stream); + + // Add any sub-nodes + if (tok == TOKEN_OpenBrace) + { + // Parse nodes + nextToken(stream); + parseNodes(stream, newNode); + // Check for matching closing brace + if (tok != TOKEN_CloseBrace) + { + throw std::runtime_error("Parse Error: Expecting closing brace"); + } + nextToken(stream); + skipNewLines(stream); + } + + break; + + // Out of place brace + case TOKEN_OpenBrace: + throw std::runtime_error("Parse Error: Opening brace out of plane"); + break; + + // Return if end of nodes have been reached + case TOKEN_CloseBrace: + return; + + // Return if reached end of file + case TOKEN_EOF: + return; + + case TOKEN_NewLine: + nextToken(stream); + break; + + default: + break; + } + } +} + +ConfigNode::ConfigNode(ConfigNode * _parent, const std::string & _name) +{ + mName = _name; + mParent = _parent; + // For proper destruction + removeSelf = true; + mLastChildFound = -1; + + // Add self to parent's child list + // (unless this is the root node being created) + if (_parent != NULL) + { + mParent->mChildren.push_back(this); + iter = --(mParent->mChildren.end()); + } +} + +ConfigNode::~ConfigNode() +{ + // Delete all children + std::vector < ConfigNode * > ::iterator i; + for (i = mChildren.begin(); i != mChildren.end(); i++) + { + ConfigNode * node = *i; + node->removeSelf = false; + delete node; + } + mChildren.clear(); + + // Remove self from parent's child list + if (removeSelf && mParent != NULL) + { + mParent->mChildren.erase(iter); + } +} + +void ConfigNode::GetColorValues(gz::math::Color & _colorValues, + unsigned int _size) +{ + std::vector floatValues; + ConfigNode::GetValuesInFloat(floatValues); + if (floatValues.size() < _size) + { + gzerr << "Bad material file." << std::endl; + floatValues.resize(_size); + } + + // clamp the color values to valid ranges + for (unsigned int i = 0; i < floatValues.size(); ++i) + { + if (!(floatValues[i] >= 0)) + { + floatValues[i] = 0; + } + if (floatValues[i] > 1) + { + floatValues[i] = floatValues[i]/255.0f; + } + } + + if (_size == 3) + { + _colorValues = gz::math::Color(floatValues[0], floatValues[1], + floatValues[2]); + } + if (_size == 4) + { + _colorValues = gz::math::Color(floatValues[0], floatValues[1], + floatValues[2], floatValues[3]); + } +} + +ConfigNode * ConfigNode::AddChild( + const std::string & _name, bool _replaceExisting) +{ + if (_replaceExisting) + { + ConfigNode * node = FindChild(_name, false); + if (node) + { + return node; + } + } + return new ConfigNode(this, _name); +} + +ConfigNode * ConfigNode::FindChild(const std::string & _name, bool _recursive) +{ + int indx, prevC, nextC; + int childCount = static_cast(mChildren.size()); + + if (mLastChildFound != -1) + { + // If possible, try checking nodes neighboring the last successful search + // (often nodes searched for in sequence, so this will std search speeds). + prevC = mLastChildFound - 1; + if (prevC < 0) + { + prevC = 0; + } + else if (prevC >= childCount) + { + prevC = childCount - 1; + } + nextC = mLastChildFound + 1; + if (nextC < 0) + { + nextC = 0; + } + else if (nextC >= childCount) + { + nextC = childCount - 1; + } + for (indx = prevC; indx <= nextC; ++indx) + { + ConfigNode * node = mChildren[indx]; + if (node->mName == _name) + { + mLastChildFound = indx; + return node; + } + } + + // If not found that way, search for the node from start to finish, + // avoiding the already searched area above. + for (indx = nextC + 1; indx < childCount; ++indx) + { + ConfigNode * node = mChildren[indx]; + if (node->mName == _name) + { + mLastChildFound = indx; + return node; + } + } + for (indx = 0; indx < prevC; ++indx) + { + ConfigNode * node = mChildren[indx]; + if (node->mName == _name) + { + mLastChildFound = indx; + return node; + } + } + } + else + { + // Search for the node from start to finish + for (indx = 0; indx < childCount; ++indx) + { + ConfigNode * node = mChildren[indx]; + if (node->mName == _name) + { + mLastChildFound = indx; + return node; + } + } + } + + // If not found, search child nodes (if recursive == true) + if (_recursive) + { + for (indx = 0; indx < childCount; ++indx) + { + mChildren[indx]->FindChild(_name, _recursive); + } + } + + // Not found anywhere + return NULL; +} + +void ConfigNode::SetParent(ConfigNode * _newParent) +{ + // Remove self from current parent + mParent->mChildren.erase(iter); + + // Set new parent + mParent = _newParent; + + // Add self to new parent + mParent->mChildren.push_back(this); + iter = --(mParent->mChildren.end()); +} diff --git a/src/rendering/MaterialParser/ConfigLoader.hh b/src/rendering/MaterialParser/ConfigLoader.hh new file mode 100644 index 0000000000..569573940b --- /dev/null +++ b/src/rendering/MaterialParser/ConfigLoader.hh @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2023 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +// This code is adapted from https://wiki.ogre3d.org/All-purpose+script+parser + +#ifndef RENDERING__MATERIALPARSER__CONFIGLOADER_HH_ +#define RENDERING__MATERIALPARSER__CONFIGLOADER_HH_ + +#include +#include +#include +#include +#include + +namespace gz +{ +namespace sim +{ +class ConfigNode; + +class ConfigLoader +{ +public: + static void LoadMaterialFiles(ConfigLoader * _c); + + ConfigLoader(); + + ~ConfigLoader(); + + // For a line like + // entity animals/dog + // { + // ... + // } + // The type is "entity" and the name is "animals/dog" + // Or if animal/dog was not there then name is "" + virtual ConfigNode * GetConfigScript(const std::string & _name); + + virtual std::map GetAllConfigScripts(); + + virtual void ParseScript(std::ifstream & _stream); + +protected: + std::map mScriptList; + + enum Token + { + TOKEN_Text, + TOKEN_NewLine, + TOKEN_OpenBrace, + TOKEN_CloseBrace, + TOKEN_EOF, + }; + + Token tok, lastTok; + std::string tokVal, lastTokVal; + + void parseNodes(std::ifstream & stream, ConfigNode * parent); + void nextToken(std::ifstream & stream); + void skipNewLines(std::ifstream & stream); + + virtual void clearScriptList(); +}; + +class ConfigNode +{ +public: + explicit ConfigNode(ConfigNode * _parent, + const std::string & _name = "untitled"); + + ~ConfigNode(); + + inline void SetName(const std::string & _name) + { + this->mName = _name; + } + + inline std::string & GetName() + { + return mName; + } + + inline void AddValue(const std::string & _value) + { + mValues.push_back(_value); + } + + inline void ClearValues() + { + mValues.clear(); + } + + inline std::vector & GetValues() + { + return mValues; + } + + inline const std::string & GetValue(unsigned int index = 0) + { + assert(index < mValues.size()); + return mValues[index]; + } + + inline void GetValuesInFloat(std::vector & floatValues) + { + for (const auto & str : mValues) + { + floatValues.push_back(std::stof(str)); + } + } + + void GetColorValues(math::Color & _colorValues, unsigned int _size); + + ConfigNode * AddChild( + const std::string & _name = "untitled", bool _replaceExisting = false); + + ConfigNode * FindChild(const std::string & _name, bool _recursive = false); + + inline std::vector & GetChildren() + { + return mChildren; + } + + inline ConfigNode * GetChild(unsigned int index = 0) + { + assert(index < mChildren.size()); + return mChildren[index]; + } + + void SetParent(ConfigNode * newParent); + + inline ConfigNode * GetParent() + { + return mParent; + } + +private: + std::string mName; + + std::vector mValues; + + std::vector mChildren; + + ConfigNode * mParent; + + // The last child node's index found with a call to findChild() + int mLastChildFound; + + std::vector ::iterator iter; + + bool removeSelf; +}; +} // namespace sim +} // namespace gz + +#endif // RENDERING__MATERIALPARSER__CONFIGLOADER_HH_ diff --git a/src/rendering/MaterialParser/MaterialParser.cc b/src/rendering/MaterialParser/MaterialParser.cc new file mode 100644 index 0000000000..d85b7d783f --- /dev/null +++ b/src/rendering/MaterialParser/MaterialParser.cc @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2023 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include +#include + +#include "MaterialParser.hh" + +using namespace gz; +using namespace sim; + +///////////////////////////////////////////////// +MaterialParser::MaterialParser() + : configLoader() +{ +} + +///////////////////////////////////////////////// +void MaterialParser::Load() +{ + ConfigLoader::LoadMaterialFiles(&this->configLoader); +} + +///////////////////////////////////////////////// +std::optional MaterialParser::GetMaterialValues( + const std::string& _material) +{ + std::optional values = std::nullopt; + std::map scripts = + this->configLoader.GetAllConfigScripts(); + + std::map ::iterator it; + + for (it = scripts.begin(); it != scripts.end(); ++it) + { + std::string name = it->first; + if (name.find(_material) != std::string::npos) + { + if (!values) + { + values = MaterialValues(); + } + ConfigNode * node = it->second; + + ConfigNode * techniqueNode = node->FindChild("technique"); + if (techniqueNode) + { + ConfigNode * passNode = techniqueNode->FindChild("pass"); + if (passNode) + { + ConfigNode * ambientNode = passNode->FindChild("ambient"); + if (ambientNode) + { + gz::math::Color ambientValues; + ambientNode->GetColorValues(ambientValues, 3); + values->ambient.emplace(ambientValues); + } + + ConfigNode * diffuseNode = passNode->FindChild("diffuse"); + if (diffuseNode) + { + gz::math::Color diffuseValues; + diffuseNode->GetColorValues(diffuseValues, 3); + values->diffuse.emplace(diffuseValues); + } + + ConfigNode * specularNode = passNode->FindChild("specular"); + if (specularNode) + { + gz::math::Color specularValues; + specularNode->GetColorValues(specularValues, 4); + // Using first four values for specular as + // Gazebo doesn't support shininess + values->specular.emplace(specularValues); + } + } + } + // \todo Handle dependent materials + } + } + return values; +} diff --git a/src/rendering/MaterialParser/MaterialParser.hh b/src/rendering/MaterialParser/MaterialParser.hh new file mode 100644 index 0000000000..b3df18643b --- /dev/null +++ b/src/rendering/MaterialParser/MaterialParser.hh @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2023 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef RENDERING__MATERIALPARSER__MATERIALPARSER_HH_ +#define RENDERING__MATERIALPARSER__MATERIALPARSER_HH_ + +#include +#include + +#include + +#include "ConfigLoader.hh" + +namespace gz +{ +namespace sim +{ +class MaterialParser +{ + public: + struct MaterialValues + { + std::optional ambient; + std::optional diffuse; + std::optional specular; + }; + + MaterialParser(); + + void Load(); + + std::optional GetMaterialValues(const std::string& _material); + + private: + ConfigLoader configLoader; +}; +} // namespace sim +} // namespace gz + +#endif // RENDERING__MATERIALPARSER__MATERIALPARSER_HH_ diff --git a/src/rendering/MaterialParser/gazebo.material b/src/rendering/MaterialParser/gazebo.material new file mode 100644 index 0000000000..4e96dc2c76 --- /dev/null +++ b/src/rendering/MaterialParser/gazebo.material @@ -0,0 +1,1721 @@ +vertex_program grid_vp_glsl glsl +{ + source grid_vp.glsl +} + +fragment_program grid_fp_glsl glsl +{ + source grid_fp.glsl +} + +material grid +{ + technique + { + pass + { + vertex_program_ref grid_vp_glsl {} + fragment_program_ref grid_fp_glsl {} + } + } +} + +vertex_program Gazebo/DepthMapVS glsl +{ + source depth_map.vert + + default_params + { + param_named_auto texelOffsets texel_offsets + } +} + +fragment_program Gazebo/DepthMapFS glsl +{ + source depth_map.frag + + default_params + { + param_named_auto pNear near_clip_distance + param_named_auto pFar far_clip_distance + } +} + +material Gazebo/DepthMap +{ + technique + { + pass + { + vertex_program_ref Gazebo/DepthMapVS { } + fragment_program_ref Gazebo/DepthMapFS { } + } + } +} + +vertex_program Gazebo/XYZPointsVS glsl +{ + source depth_points_map.vert +} + +fragment_program Gazebo/XYZPointsFS glsl +{ + source depth_points_map.frag + + default_params + { + param_named_auto width viewport_width + param_named_auto height viewport_height + } +} + +material Gazebo/XYZPoints +{ + technique + { + pass pcd_tex + { + separate_scene_blend one zero one zero + + vertex_program_ref Gazebo/XYZPointsVS { } + fragment_program_ref Gazebo/XYZPointsFS { } + } + } +} + +material Gazebo/Reflectance +{ + technique + { + pass + { + lighting off + texture_unit + { + } + } + } +} + +vertex_program Gazebo/XYZNormalsVS glsl +{ + source depth_normals_map.vert +} + +fragment_program Gazebo/XYZNormalsFS glsl +{ + source depth_normals_map.frag +} + +material Gazebo/XYZNormals +{ + technique + { + pass normals_tex + { + separate_scene_blend one zero one zero + + vertex_program_ref Gazebo/XYZNormalsVS { } + fragment_program_ref Gazebo/XYZNormalsFS { } + } + } +} + +vertex_program Gazebo/LaserScan1stVS glsl +{ + source laser_1st_pass.vert +} + +fragment_program Gazebo/LaserScan1stFS glsl +{ + source laser_1st_pass.frag + + default_params + { + param_named retro float 0.0 + param_named_auto near near_clip_distance + param_named_auto far far_clip_distance + } +} + +material Gazebo/LaserScan1st +{ + technique + { + pass laser_tex + { + separate_scene_blend one zero one zero + + vertex_program_ref Gazebo/LaserScan1stVS { } + fragment_program_ref Gazebo/LaserScan1stFS { } + } + } +} + +vertex_program Gazebo/LaserScan2ndVS glsl +{ + source laser_2nd_pass.vert +} + +fragment_program Gazebo/LaserScan2ndFS glsl +{ + source laser_2nd_pass.frag + + default_params + { + param_named tex1 int 0 + param_named tex2 int 1 + param_named tex3 int 2 + param_named_auto texSize texture_size 0 + } +} + +material Gazebo/LaserScan2nd +{ + technique + { + pass laser_tex_2nd + { + separate_scene_blend one zero one zero + + vertex_program_ref Gazebo/LaserScan2ndVS { } + fragment_program_ref Gazebo/LaserScan2ndFS { } + } + } +} + +material Gazebo/Grey +{ + technique + { + pass main + { + ambient .3 .3 .3 1.0 + diffuse .7 .7 .7 1.0 + specular 0.01 0.01 0.01 1.000000 1.500000 + } + } +} +material Gazebo/Gray : Gazebo/Grey +{ + technique + { + pass main + { + ambient .3 .3 .3 1.0 + diffuse .7 .7 .7 1.0 + specular 0.01 0.01 0.01 1.000000 1.500000 + } + } +} + +material Gazebo/DarkGrey +{ + technique + { + pass main + { + ambient .175 .175 .175 1.0 + diffuse .175 .175 .175 1.0 + specular .175 .175 .175 1.000000 1.500000 + } + } +} + +material Gazebo/DarkGray : Gazebo/DarkGrey +{ + technique + { + pass main + { + ambient .175 .175 .175 1.0 + diffuse .175 .175 .175 1.0 + specular .175 .175 .175 1.000000 1.500000 + } + } +} + +material Gazebo/White +{ + technique + { + pass ambient + { + ambient 1 1 1 1 + diffuse 1 1 1 1 + specular .1 .1 .1 128 + } + } +} + +material Gazebo/FlatBlack +{ + technique + { + pass + { + ambient 0.1 0.1 0.1 + diffuse 0.1 0.1 0.1 + specular 0.01 0.01 0.01 1.0 1.0 + } + } +} + +material Gazebo/Black +{ + technique + { + pass + { + ambient 0 0 0 1 + diffuse 0 0 0 1 + specular 0.1 0.1 0.1 1 5.0 + } + } +} + + +material Gazebo/Red +{ + technique + { + pass ambient + { + ambient 1 0 0 + diffuse 1 0 0 + specular 0.1 0.1 0.1 1 1 + } + } +} + +material Gazebo/RedBright +{ + technique + { + pass ambient + { + ambient 0.87 0.26 0.07 + diffuse 0.87 0.26 0.07 + specular 0.87 0.26 0.07 1 1 + } + } +} + +material Gazebo/Green +{ + technique + { + pass ambient + { + ambient 0 1 0 + diffuse 0 1 0 + specular 0.1 0.1 0.1 1 1 + } + } +} + +material Gazebo/Blue +{ + technique + { + pass ambient + { + ambient 0 0 1 + diffuse 0 0 1 + specular 0.1 0.1 0.1 1 1 + } + } +} + +material Gazebo/SkyBlue +{ + technique + { + pass ambient + { + ambient 0.13 0.44 0.70 + diffuse 0 0 1 + specular 0.1 0.1 0.1 1 1 + } + } +} + +material Gazebo/Yellow +{ + technique + { + pass ambient + { + ambient 1 1 0 1 + diffuse 1 1 0 1 + specular 0 0 0 0 0 + } + } +} + +material Gazebo/ZincYellow +{ + technique + { + pass ambient + { + ambient 0.9725 0.9529 0.2078 1 + diffuse 0.9725 0.9529 0.2078 1 + specular 0.9725 0.9529 0.2078 1 1 + } + } +} + +material Gazebo/DarkYellow +{ + technique + { + pass ambient + { + ambient 0.7 0.7 0 1 + diffuse 0.7 0.7 0 1 + specular 0 0 0 0 0 + } + } +} + + +material Gazebo/Purple +{ + technique + { + pass ambient + { + ambient 1 0 1 + diffuse 1 0 1 + specular 0.1 0.1 0.1 1 1 + } + } +} + +material Gazebo/Turquoise +{ + technique + { + pass ambient + { + ambient 0 1 1 + diffuse 0 1 1 + specular 0.1 0.1 0.1 1 1 + } + } +} + +material Gazebo/Orange +{ + technique + { + pass ambient + { + lighting on + + ambient 1 0.5088 0.0468 1 + diffuse 1 0.5088 0.0468 1 + specular 0.5 0.5 0.5 128 + } + } +} + +material Gazebo/Indigo +{ + technique + { + pass ambient + { + ambient 0.33 0.0 0.5 + diffuse 0.33 0.0 0.5 + specular 0.1 0.1 0.1 1 + } + } +} + +material Gazebo/WhiteGlow : Gazebo/White +{ + technique + { + pass light + { + emissive 1 1 1 + } + } +} + +material Gazebo/RedGlow +{ + technique + { + pass ambient + { + ambient 1 0 0 + diffuse 1 0 0 + emissive 1 0 0 + specular 0 0 0 128 + } + + pass light + { + ambient 1 0 0 + diffuse 1 0 0 + emissive 1 0 0 + specular 1 0 0 128 + } + } +} + + + +material Gazebo/GreenGlow : Gazebo/Green +{ + technique + { + pass ambient + { + emissive 0 1 0 + } + + pass light + { + emissive 0 1 0 + } + } +} + +material Gazebo/BlueGlow : Gazebo/Blue +{ + technique + { + pass light + { + emissive 0 0 1 + } + } +} + +material Gazebo/YellowGlow : Gazebo/Yellow +{ + technique + { + pass light + { + emissive 1 1 0 + } + } +} + +material Gazebo/PurpleGlow : Gazebo/Purple +{ + technique + { + pass light + { + emissive 1 0 1 + } + } +} + +material Gazebo/TurquoiseGlow : Gazebo/Turquoise +{ + technique + { + pass light + { + emissive 0 1 1 + } + } +} + +material Gazebo/TurquoiseGlowOutline +{ + technique + { + pass ambient + { + scene_blend alpha_blend + //lighting off + + diffuse 0 1 1 1 + specular .1 .1 .1 128 + } + + pass ambient2 + { + scene_blend alpha_blend + + diffuse 0 1 1 + specular .1 .1 .1 128 + emissive 0 1 1 + + polygon_mode wireframe + } + } +} + +material Gazebo/RedTransparentOverlay +{ + technique + { + pass + { + scene_blend alpha_blend + depth_write off + lighting off + depth_check off + + texture_unit + { + colour_op_ex source1 src_manual src_current 1 0 0 + alpha_op_ex source1 src_manual src_current 0.5 + } + } + } +} + +material Gazebo/BlueTransparentOverlay +{ + technique + { + pass + { + scene_blend alpha_blend + depth_write off + lighting off + depth_check off + + texture_unit + { + colour_op_ex source1 src_manual src_current 0 0 1 + alpha_op_ex source1 src_manual src_current 0.5 + } + } + } +} + +material Gazebo/GreenTransparentOverlay +{ + technique + { + pass + { + scene_blend alpha_blend + depth_write off + lighting off + depth_check off + + texture_unit + { + colour_op_ex source1 src_manual src_current 0 1 0 + alpha_op_ex source1 src_manual src_current 0.5 + } + } + } +} + +material Gazebo/OrangeTransparentOverlay +{ + technique + { + pass + { + scene_blend alpha_blend + depth_write off + lighting off + depth_check off + ambient 1 0.5088 0.0468 + + texture_unit + { + colour_op_ex source1 src_manual src_current 1 0.5088 0.0468 + alpha_op_ex source1 src_manual src_current 0.8 + } + } + } +} + +material Gazebo/DarkOrangeTransparentOverlay +{ + technique + { + pass + { + scene_blend alpha_blend + depth_write off + lighting off + depth_check off + ambient 0.6 0.305 0.028 + + texture_unit + { + colour_op_ex source1 src_manual src_current 0.6 0.305 0.028 + alpha_op_ex source1 src_manual src_current 0.8 + } + } + } +} + +material Gazebo/RedTransparent +{ + technique + { + pass + { + scene_blend alpha_blend + depth_write off + lighting off + + texture_unit + { + colour_op_ex source1 src_manual src_current 1 0 0 + alpha_op_ex source1 src_manual src_current 0.5 + } + } + } +} + +material Gazebo/GreenTransparent +{ + technique + { + pass + { + scene_blend alpha_blend + depth_write off + + ambient 0.0 1.0 0.0 1 + diffuse 0.0 1.0 0.0 1 + + texture_unit + { + colour_op_ex source1 src_current src_current 0 1 0 + alpha_op_ex source1 src_manual src_current 0.5 + } + } + } +} + +material Gazebo/BlueTransparent +{ + technique + { + pass + { + scene_blend alpha_blend + depth_write off + + ambient 0.0 0.0 1.0 1 + diffuse 0.0 0.0 1.0 1 + + texture_unit + { + colour_op_ex source1 src_current src_current 0 1 0 + alpha_op_ex source1 src_manual src_current 0.5 + } + } + } +} + +material Gazebo/DarkMagentaTransparent +{ + technique + { + pass + { + scene_blend alpha_blend + depth_write off + + ambient 0.6 0.0 0.6 1 + diffuse 0.6 0.0 0.6 1 + + texture_unit + { + colour_op_ex source1 src_current src_current 0.6 0 0.6 + alpha_op_ex source1 src_manual src_current 0.5 + } + } + } +} + +material Gazebo/GreyTransparent +{ + technique + { + pass + { + scene_blend alpha_blend + depth_write off + + ambient 0.5 0.5 0.5 1 + diffuse 0.5 0.5 0.5 1 + + texture_unit + { + colour_op_ex source1 src_current src_current 0 1 0 + alpha_op_ex source1 src_manual src_current 0.5 + } + } + } +} + +material Gazebo/BlackTransparent +{ + technique + { + pass + { + scene_blend alpha_blend + depth_write off + + ambient 0.0 0.0 0.0 1 + diffuse 0.0 0.0 0.0 1 + + texture_unit + { + colour_op_ex source1 src_current src_current 0 1 0 + alpha_op_ex source1 src_manual src_current 0.5 + } + } + } +} + +material Gazebo/YellowTransparent +{ + technique + { + pass + { + scene_blend alpha_blend + depth_write off + + ambient 1.0 1.0 0.0 1 + diffuse 1.0 1.0 0.0 1 + + texture_unit + { + colour_op_ex source1 src_current src_current 0 1 0 + alpha_op_ex source1 src_manual src_current 0.5 + } + } + } +} + +material Gazebo/LightOn +{ + technique + { + pass ambient + { + diffuse 0 1 0 + ambient 0 1 0 + emissive 0 1 0 + } + } +} + +material Gazebo/LightOff +{ + technique + { + pass ambient + { + diffuse 1 0 0 + ambient 1 0 0 + emissive 1 0 0 + } + } +} + +material Gazebo/LightBlueLaser +{ + receive_shadows off + + technique + { + pass + { + scene_blend alpha_blend + depth_write off + cull_hardware none + + ambient 0.5 0.5 1.0 1 + diffuse 0.5 0.5 1.0 1 + + texture_unit + { + colour_op_ex source1 src_current src_current 0 1 0 + alpha_op_ex source1 src_manual src_current 0.4 + } + + } + } +} + +material Gazebo/BlueLaser +{ + receive_shadows off + + technique + { + pass + { + scene_blend alpha_blend + depth_write off + cull_hardware none + + ambient 0.0 0.0 1.0 1 + diffuse 0.0 0.0 1.0 1 + + texture_unit + { + colour_op_ex source1 src_current src_current 0 1 0 + alpha_op_ex source1 src_manual src_current 0.4 + } + + } + } +} + +material Gazebo/OrangeTransparent +{ + receive_shadows off + + technique + { + pass + { + scene_blend alpha_blend + depth_write off + + ambient 1.0 0.44 0.0 1 + diffuse 1.0 0.44 0.0 1 + + texture_unit + { + colour_op_ex source1 src_current src_current 0 1 0 + alpha_op_ex source1 src_manual src_current 0.4 + } + + } + } +} + + +material Gazebo/JointAnchor +{ + receive_shadows off + + technique + { + pass + { + ambient 1.000000 1.000000 1.000000 1.000000 + diffuse 1.000000 1.000000 1.000000 1.000000 + specular 1.000000 1.000000 1.000000 1.000000 + emissive 1.000000 1.000000 1.000000 1.000000 + lighting off + } + } +} + +material Gazebo/CoM +{ + technique + { + pass + { + ambient 0.5 0.5 0.5 1.000000 + + texture_unit + { + texture com.png + } + } + } +} + +material Gazebo/WoodFloor +{ + receive_shadows on + + technique + { + pass + { + ambient 0.5 0.5 0.5 1.000000 + + texture_unit + { + texture hardwood_floor.jpg + } + } + } +} + +material Gazebo/CeilingTiled +{ + receive_shadows on + + technique + { + pass + { + ambient 0.5 0.5 0.5 1.000000 + + texture_unit + { + texture ceiling_tiled.jpg + } + } + } +} + +material Gazebo/PaintedWall +{ + receive_shadows on + + technique + { + pass + { + ambient 1.0 1.0 1.0 1.000000 + + texture_unit + { + texture paintedWall.jpg + } + } + } +} + +material Gazebo/PioneerBody +{ + receive_shadows on + technique + { + pass Ambient + { + ambient 0.5 0 0 + + texture_unit + { + texture pioneerBody.jpg + filtering trilinear + } + } + pass DirectionalLight + { + ambient 0 0 0 + diffuse 1 0 0 1 + specular 0.5 0 0 1 10 + + texture_unit + { + texture pioneerBody.jpg + filtering trilinear + } + } + pass PointLight + { + ambient 0 0 0 + diffuse 1 0 0 1 + specular 0.5 0 0 1 10 + + texture_unit + { + texture pioneerBody.jpg + filtering trilinear + } + } + + } +} + +material Gazebo/Pioneer2Body +{ + receive_shadows on + technique + { + pass + { + //ambient 0.500000 0.500000 0.500000 1.000000 + ambient 0.481193 0.000123 0.000123 1.000000 + diffuse 0.681193 0.000923 0.000923 1.000000 + specular 0.500000 0.500000 0.500000 1.000000 12.500000 + emissive 0.000000 0.000000 0.000000 1.000000 + } + } +} + +material Gazebo/Gold +{ + receive_shadows on + technique + { + pass + { + ambient 0.400000 0.248690 0.020759 1.000000 + diffuse 0.800000 0.648690 0.120759 1.000000 + specular 0.400000 0.400000 0.400000 1.000000 12.500000 + } + } +} + +material Gazebo/GreyGradientSky +{ + technique + { + pass + { + depth_write off + lighting off + + texture_unit + { + texture grey_gradient.jpg + } + } + } +} + +material Gazebo/CloudySky +{ + technique + { + pass + { + depth_write off + lighting off + + texture_unit + { + texture clouds.jpg + scroll_anim 0.15 0 + } + } + } +} + +material Gazebo/WoodPallet +{ + technique + { + pass + { + ambient 0.5 0.5 0.5 1.0 + diffuse 1.0 1.0 1.0 1.0 + specular 0.0 0.0 0.0 1.0 0.5 + + texture_unit + { + texture WoodPallet.png + filtering trilinear + } + } + } + + /* + technique + { + scheme GBuffer + pass DeferredShading/GBuffer/Pass_16 + { + lighting off + + vertex_program_ref Gazebo/NateVS + { + } + + fragment_program_ref Gazebo/NateFS + { + } + } + }*/ +} + +material Gazebo/Wood +{ + technique + { + pass + { + ambient 1.0 1.0 1.0 1.0 + diffuse 1.0 1.0 1.0 1.0 + specular 0.2 0.2 0.2 1.0 12.5 + + texture_unit + { + texture wood.jpg + filtering trilinear + } + } + } +} + +material Gazebo/Bricks +{ + technique + { + pass + { + ambient 1.0 1.0 1.0 1.0 + diffuse 1.0 1.0 1.0 1.0 + specular 0.2 0.2 0.2 1.0 12.5 + + texture_unit + { + texture bricks.png + filtering trilinear + } + } + } +} + +material Gazebo/Road +{ + technique + { + pass + { + ambient 0.1 0.1 0.1 1.0 + diffuse 0.8 0.8 0.8 1.0 + specular 0.01 0.01 0.01 1.0 2.0 + + texture_unit + { + texture road1.jpg + filtering trilinear + } + } + } +} + +material Gazebo/Residential +{ + technique + { + pass + { + ambient 0.1 0.1 0.1 1.0 + diffuse 0.8 0.8 0.8 1.0 + specular 0.01 0.01 0.01 1.0 2.0 + + texture_unit + { + texture residential.jpg + filtering trilinear + } + } + } +} + +material Gazebo/Tertiary +{ + technique + { + pass + { + ambient 0.1 0.1 0.1 1.0 + diffuse 0.8 0.8 0.8 1.0 + specular 0.01 0.01 0.01 1.0 2.0 + + texture_unit + { + texture residential.jpg + filtering trilinear + } + } + } +} + +material Gazebo/Pedestrian +{ + technique + { + pass + { + ambient 0.1 0.1 0.1 1.0 + diffuse 0.8 0.8 0.8 1.0 + specular 0.01 0.01 0.01 1.0 2.0 + + texture_unit + { + texture sidewalk.jpg + filtering trilinear + } + } + } +} + +material Gazebo/Footway +{ + technique + { + pass + { + ambient 0.1 0.1 0.1 1.0 + diffuse 0.8 0.8 0.8 1.0 + specular 0.01 0.01 0.01 1.0 2.0 + + texture_unit + { + texture sidewalk.jpg + filtering trilinear + } + } + } +} + +material Gazebo/Motorway +{ + technique + { + pass + { + ambient 0.1 0.1 0.1 1.0 + diffuse 0.8 0.8 0.8 1.0 + specular 0.01 0.01 0.01 1.0 2.0 + + texture_unit + { + texture motorway.jpg + filtering trilinear + } + } + } +} + +material Gazebo/Lanes_6 +{ + technique + { + pass + { + ambient 0.1 0.1 0.1 1.0 + diffuse 0.8 0.8 0.8 1.0 + specular 0.01 0.01 0.01 1.0 2.0 + + texture_unit + { + texture motorway.jpg + filtering trilinear + } + } + } +} + +material Gazebo/Trunk +{ + technique + { + pass + { + ambient 0.1 0.1 0.1 1.0 + diffuse 0.8 0.8 0.8 1.0 + specular 0.01 0.01 0.01 1.0 2.0 + + texture_unit + { + texture trunk.jpg + filtering trilinear + } + } + } +} + +material Gazebo/Lanes_4 +{ + technique + { + pass + { + ambient 0.1 0.1 0.1 1.0 + diffuse 0.8 0.8 0.8 1.0 + specular 0.01 0.01 0.01 1.0 2.0 + + texture_unit + { + texture trunk.jpg + filtering trilinear + } + } + } +} + +material Gazebo/Primary +{ + technique + { + pass + { + ambient 0.1 0.1 0.1 1.0 + diffuse 0.8 0.8 0.8 1.0 + specular 0.01 0.01 0.01 1.0 2.0 + + texture_unit + { + texture primary.jpg + filtering trilinear + } + } + } +} + +material Gazebo/Lanes_2 +{ + technique + { + pass + { + ambient 0.1 0.1 0.1 1.0 + diffuse 0.8 0.8 0.8 1.0 + specular 0.01 0.01 0.01 1.0 2.0 + + texture_unit + { + texture primary.jpg + filtering trilinear + } + } + } +} + +material Gazebo/Secondary +{ + technique + { + pass + { + ambient 0.1 0.1 0.1 1.0 + diffuse 0.8 0.8 0.8 1.0 + specular 0.01 0.01 0.01 1.0 2.0 + + texture_unit + { + texture secondary.jpg + filtering trilinear + } + } + } +} + +material Gazebo/Lane_1 +{ + technique + { + pass + { + ambient 0.1 0.1 0.1 1.0 + diffuse 0.8 0.8 0.8 1.0 + specular 0.01 0.01 0.01 1.0 2.0 + + texture_unit + { + texture secondary.jpg + filtering trilinear + } + } + } +} + +material Gazebo/Steps +{ + technique + { + pass + { + ambient 0.1 0.1 0.1 1.0 + diffuse 0.8 0.8 0.8 1.0 + specular 0.01 0.01 0.01 1.0 2.0 + + texture_unit + { + texture steps.jpeg + filtering trilinear + } + } + } +} + +material drc/san_fauxcity_sign +{ + receive_shadows off + technique + { + pass + { + ambient 0.8 0.8 0.8 1.0 + diffuse 0.8 0.8 0.8 1.0 + specular 0.1 0.1 0.1 1.0 2.0 + + texture_unit + { + texture san_fauxcity.png + filtering trilinear + } + } + } +} + +vertex_program Gazebo/GaussianCameraNoiseVS glsl +{ + source camera_noise_gaussian_vs.glsl +} + +fragment_program Gazebo/GaussianCameraNoiseFS glsl +{ + source camera_noise_gaussian_fs.glsl + default_params + { + param_named RT int 0 + param_named mean float 0.0 + param_named stddev float 1.0 + param_named offsets float3 0.0 0.0 0.0 + } +} + +material Gazebo/GaussianCameraNoise +{ + technique + { + pass + { + vertex_program_ref Gazebo/GaussianCameraNoiseVS { } + fragment_program_ref Gazebo/GaussianCameraNoiseFS { } + + texture_unit RT + { + tex_coord_set 0 + tex_address_mode clamp + filtering linear linear linear + } + } + } +} + +vertex_program Gazebo/CameraDistortionMapVS glsl +{ + source camera_distortion_map_vs.glsl +} + +fragment_program Gazebo/CameraDistortionMapFS glsl +{ + source camera_distortion_map_fs.glsl + default_params + { + param_named RT int 0 + param_named distortionMap int 1 + param_named scale float3 1.0 1.0 1.0 + } +} + +material Gazebo/CameraDistortionMap +{ + technique + { + pass + { + vertex_program_ref Gazebo/CameraDistortionMapVS { } + fragment_program_ref Gazebo/CameraDistortionMapFS { } + + texture_unit RT + { + tex_coord_set 0 + tex_address_mode border + filtering linear linear linear + } + } + } +} + +vertex_program Gazebo/WideLensMapVS glsl +{ + source wide_lens_map_vs.glsl + default_params + { + param_named ratio float 1 + } +} + +fragment_program Gazebo/WideLensMapFS glsl +{ + source wide_lens_map_fp.glsl + default_params + { + param_named envMap int 0 + param_named c1 float 1 + param_named c2 float 1 + param_named c3 float 0 + param_named f float 1 + param_named fun float3 0 0 1 + param_named cutOffAngle float 3.14 + } +} + +material Gazebo/WideLensMap +{ + technique + { + pass + { + vertex_program_ref Gazebo/WideLensMapVS { } + fragment_program_ref Gazebo/WideLensMapFS { } + } + } +} + + +vertex_program Gazebo/CameraLensFlareVS glsl +{ + source camera_lens_flare_vs.glsl +} + +fragment_program Gazebo/CameraLensFlareFS glsl +{ + source camera_lens_flare_fs.glsl + + default_params + { + param_named RT int 0 + param_named viewport float3 0.0 0.0 0.0 + param_named lightPos float3 0 0 0 + param_named scale float 1.0 + param_named color float3 1.4 1.2 1.0 + } +} + +material Gazebo/CameraLensFlare +{ + technique + { + pass + { + vertex_program_ref Gazebo/CameraLensFlareVS { } + fragment_program_ref Gazebo/CameraLensFlareFS { } + + texture_unit RT + { + tex_coord_set 0 + tex_address_mode border + filtering linear linear linear + } + } + } +} + +material Gazebo/PointCloud +{ + technique + { + pass + { + diffuse vertexcolour + specular vertexcolour + ambient vertexcolour + point_size 3 + point_sprites off + point_size_attenuation off + } + } +} + +material Gazebo/PointHandle +{ + technique + { + pass + { + lighting off + scene_blend alpha_blend + depth_write off + } + } +} + +material Gazebo/BuildingFrame +{ + technique + { + pass + { + ambient 1.0 1.0 1.0 1.0 + diffuse 1.0 1.0 1.0 1.0 + specular 0.2 0.2 0.2 1.0 12.5 + + texture_unit + { + texture building_frame.png + filtering trilinear + } + } + } +} + +material Gazebo/Runway +{ + receive_shadows on + + technique + { + pass + { + ambient 0.5 0.5 0.5 1.000000 + + texture_unit + { + texture runway.png + } + } + } +} + +material Gazebo/Grass +{ + receive_shadows on + + technique + { + pass + { + ambient 0.5 0.5 0.5 1.000000 + + texture_unit + { + scale .02 .02 + texture grass.jpg + filtering anisotropic + max_anisotropy 16 + } + } + } +} + +material Gazebo/Editor +{ + technique + { + pass ambient + { + ambient 1.0 1.0 1.0 1.0 + diffuse 1.0 1.0 1.0 1 + specular .1 .1 .1 128 + } + } +} + +material Gazebo/EditorPlane +{ + technique + { + pass + { + scene_blend colour_blend + + ambient .3 .3 .3 1.0 + diffuse .7 .7 .7 1.0 + specular 0.01 0.01 0.01 1.000000 1.500000 + } + } +} diff --git a/test/integration/CMakeLists.txt b/test/integration/CMakeLists.txt index fedae18b24..96bfdfbc02 100644 --- a/test/integration/CMakeLists.txt +++ b/test/integration/CMakeLists.txt @@ -48,6 +48,7 @@ set(tests logical_camera_system.cc logical_audio_sensor_plugin.cc magnetometer_system.cc + material.cc model.cc model_photo_shoot_default_joints.cc model_photo_shoot_random_joints.cc diff --git a/test/integration/material.cc b/test/integration/material.cc new file mode 100644 index 0000000000..a5f4c8da46 --- /dev/null +++ b/test/integration/material.cc @@ -0,0 +1,298 @@ +/* + * Copyright (C) 2023 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include + +#include +#include + +#include +#include + +#include + +#include "gz/sim/EntityComponentManager.hh" +#include "gz/sim/EventManager.hh" +#include "gz/sim/Model.hh" +#include "gz/sim/SdfEntityCreator.hh" +#include "gz/sim/Server.hh" +#include "gz/sim/SystemLoader.hh" +#include "gz/sim/Types.hh" +#include "test_config.hh" + +#include "gz/sim/components/Material.hh" +#include "gz/sim/components/Model.hh" +#include "gz/sim/components/Name.hh" +#include "gz/sim/components/Visual.hh" +#include "gz/sim/components/World.hh" + +#include "../helpers/Relay.hh" +#include "../helpers/EnvTestFixture.hh" + +using namespace gz; +using namespace sim; + +class MaterialTest : public InternalFixture<::testing::Test> +{ + public: ::testing::AssertionResult StartServer( + const gz::sim::ServerConfig &_serverConfig = + gz::sim::ServerConfig()) + { + this->relay = std::make_unique(); + this->server = std::make_unique(_serverConfig); + using namespace std::chrono_literals; + this->server->SetUpdatePeriod(0ns); + + EXPECT_FALSE(this->server->Running()); + EXPECT_FALSE(*this->server->Running(0)); + // A pointer to the ecm. This will be valid once we run the mock system + relay->OnPreUpdate( + [this](const UpdateInfo &, EntityComponentManager &_ecm) + { + this->ecm = &_ecm; + }); + + this->server->AddSystem(this->relay->systemPtr); + this->server->Run(true, 1, false); + if (nullptr == this->ecm) + { + return ::testing::AssertionFailure() + << "Failed to create EntityComponentManager"; + } + + this->creator = + std::make_unique(*this->ecm, this->dummyEventMgr); + return ::testing::AssertionSuccess(); + } + + public: void SpawnModelSDF(const std::string &_sdfString) + { + ASSERT_NE(this->server, nullptr); + ASSERT_NE(this->creator, nullptr); + + sdf::Root root; + sdf::Errors errors = root.LoadSdfString(_sdfString); + EXPECT_TRUE(errors.empty()); + ASSERT_NE(nullptr, root.Model()); + + Entity modelEntity = this->creator->CreateEntities(root.Model()); + Entity worldEntity = this->ecm->EntityByComponents(components::World()); + this->creator->SetParent(modelEntity, worldEntity); + } + + public: Model GetModel(const std::string &_name) + { + return Model(this->ecm->EntityByComponents( + components::Model(), components::Name(_name))); + } + + public: std::unique_ptr relay; + public: std::unique_ptr server; + public: EntityComponentManager *ecm {nullptr}; + public: EventManager dummyEventMgr; + public: std::unique_ptr creator; +}; + +// Check for blue color parsed +TEST_F(MaterialTest, SolidColor) +{ + const std::string modelSdf = R"sdf( + + + 0 0 0.5 0 0 0 + + 0 -1.5 0 0 0 0 + + + + 1 1 1 + + + + + + + + + + )sdf"; + + ASSERT_TRUE(this->StartServer()); + this->SpawnModelSDF(modelSdf); + + auto model = this->GetModel("material_shapes"); + ASSERT_TRUE(model.Valid(*this->ecm)); + + auto boxVisualEntity = + this->ecm->EntityByComponents(components::Name("box_visual")); + ASSERT_NE(kNullEntity, boxVisualEntity); + + auto boxVisualComp = + this->ecm->Component(boxVisualEntity); + EXPECT_EQ(math::Color(0.0f, 0.0f, 1.0f, 1.0f), + boxVisualComp->Data().Ambient()); + EXPECT_EQ(math::Color(0.0f, 0.0f, 1.0f, 1.0f), + boxVisualComp->Data().Diffuse()); + EXPECT_EQ(math::Color(0.1f, 0.1f, 0.1f, 1.0f), + boxVisualComp->Data().Specular()); +} + +// Other than solid colors parsed black by default +TEST_F(MaterialTest, OtherColor) +{ + const std::string modelSdf = R"sdf( + + + 0 0 0.5 0 0 0 + + 0 -1.5 0 0 0 0 + + + + 1 1 1 + + + + + + + + + + )sdf"; + + ASSERT_TRUE(this->StartServer()); + this->SpawnModelSDF(modelSdf); + + auto model = this->GetModel("material_shapes"); + ASSERT_TRUE(model.Valid(*this->ecm)); + + auto boxVisualEntity = + this->ecm->EntityByComponents(components::Name("box_visual")); + ASSERT_NE(kNullEntity, boxVisualEntity); + + // Default to black color + auto boxVisualComp = + this->ecm->Component(boxVisualEntity); + EXPECT_EQ(math::Color(0.0f, 0.0f, 0.0f, 1.0f), + boxVisualComp->Data().Ambient()); + EXPECT_EQ(math::Color(0.0f, 0.0f, 0.0f, 1.0f), + boxVisualComp->Data().Diffuse()); + EXPECT_EQ(math::Color(0.0f, 0.0f, 0.0f, 1.0f), + boxVisualComp->Data().Specular()); +} + +// Warning for custom scripts not supported, default to black +TEST_F(MaterialTest, CustomScript) +{ + const std::string modelSdf = R"sdf( + + + 0 0 0.5 0 0 0 + + 0 -1.5 0 0 0 0 + + + + 1 1 1 + + + + + + + + + + )sdf"; + + ASSERT_TRUE(this->StartServer()); + this->SpawnModelSDF(modelSdf); + + auto model = this->GetModel("material_shapes"); + ASSERT_TRUE(model.Valid(*this->ecm)); + + auto boxVisualEntity = + this->ecm->EntityByComponents(components::Name("box_visual")); + ASSERT_NE(kNullEntity, boxVisualEntity); + + // Default to black color + auto boxVisualComp = + this->ecm->Component(boxVisualEntity); + EXPECT_EQ(math::Color(0.0f, 0.0f, 0.0f, 1.0f), + boxVisualComp->Data().Ambient()); + EXPECT_EQ(math::Color(0.0f, 0.0f, 0.0f, 1.0f), + boxVisualComp->Data().Diffuse()); + EXPECT_EQ(math::Color(0.0f, 0.0f, 0.0f, 1.0f), + boxVisualComp->Data().Specular()); +} + +// Warning for invalid name, default to black +TEST_F(MaterialTest, InvalidColor) +{ + const std::string modelSdf = R"sdf( + + + 0 0 0.5 0 0 0 + + 0 -1.5 0 0 0 0 + + + + 1 1 1 + + + + + + + + + + )sdf"; + + ASSERT_TRUE(this->StartServer()); + this->SpawnModelSDF(modelSdf); + + auto model = this->GetModel("material_shapes"); + ASSERT_TRUE(model.Valid(*this->ecm)); + + auto boxVisualEntity = + this->ecm->EntityByComponents(components::Name("box_visual")); + ASSERT_NE(kNullEntity, boxVisualEntity); + + // Default to black color + auto boxVisualComp = + this->ecm->Component(boxVisualEntity); + EXPECT_EQ(math::Color(0.0f, 0.0f, 0.0f, 1.0f), + boxVisualComp->Data().Ambient()); + EXPECT_EQ(math::Color(0.0f, 0.0f, 0.0f, 1.0f), + boxVisualComp->Data().Diffuse()); + EXPECT_EQ(math::Color(0.0f, 0.0f, 0.0f, 1.0f), + boxVisualComp->Data().Specular()); +} diff --git a/tutorials/migration_sdf.md b/tutorials/migration_sdf.md index daece419ab..4c6b618c32 100644 --- a/tutorials/migration_sdf.md +++ b/tutorials/migration_sdf.md @@ -271,8 +271,8 @@ that worked on Gazebo classic may need more plugins on Gazebo. ## Materials Gazebo does not support Ogre material files like Classic does, because Gazebo -Gazebo can be used with multiple rendering engines. Therefore, materials defined -within a `