colladaExtensions.h
Engine/source/ts/collada/colladaExtensions.h
Classes:
class
class
Extensions for the
class
Extensions for the
class
Extensions for the
Public Defines
define
GET_EXTRA_PARAM(param, defaultVal) get(#param, param, defaultVal)
Detailed Description
Public Defines
GET_EXTRA_PARAM(param, defaultVal) get(#param, param, defaultVal)
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#ifndef _COLLADA_EXTENSIONS_H_ 25#define _COLLADA_EXTENSIONS_H_ 26 27#ifndef _TSSHAPE_LOADER_H_ 28#include "ts/loader/tsShapeLoader.h" 29#endif 30#ifndef _COLLADA_UTILS_H_ 31#include "ts/collada/colladaUtils.h" 32#endif 33 34//----------------------------------------------------------------------------- 35// Collada allows custom data to be included with many elements using the <extra> 36// tag, followed by one or more named technique profiles. eg. 37// <some_element> 38// <extra> 39// <technique profile="SOME_PROFILE"> 40// <custom_element0>value0</custom_element0> 41// <custom_element1>value1</custom_element1> 42// ... 43// <technique profile="ANOTHER_PROFILE"> 44// <custom_element0>value0</custom_element0> 45// <custom_element1>value1</custom_element1> 46// ... 47// 48// This class provides an easy way to read the custom parameters into a strongly 49// typed subclass. 50class ColladaExtension 51{ 52 // Helper macro to simplify getting named parameters 53 #define GET_EXTRA_PARAM(param, defaultVal) \ 54 get(#param, param, defaultVal) 55 56protected: 57 const domTechnique* pTechnique; 58 59 /// Find the technique with the named profile 60 template<class T> const domTechnique* findExtraTechnique(const T* element, const char* name) const 61 { 62 if (element) { 63 for (S32 iExt = 0; iExt < element->getExtra_array().getCount(); iExt++) { 64 for (S32 iTech = 0; iTech < element->getExtra_array()[iExt]->getTechnique_array().getCount(); iTech++) { 65 if (dStrEqual(element->getExtra_array()[iExt]->getTechnique_array()[iTech]->getProfile(), name)) 66 return element->getExtra_array()[iExt]->getTechnique_array()[iTech]; 67 } 68 } 69 } 70 return NULL; 71 } 72 73 /// The <texture> element does not define an extra_array, so need a specialized 74 /// version of the template 75 const domTechnique* findExtraTechnique( 76 const domCommon_color_or_texture_type_complexType::domTexture* element, const char* name) const 77 { 78 if (element && element->getExtra()) { 79 for (S32 iTech = 0; iTech < element->getExtra()->getTechnique_array().getCount(); iTech++) { 80 if (dStrEqual(element->getExtra()->getTechnique_array()[iTech]->getProfile(), name)) 81 return element->getExtra()->getTechnique_array()[iTech]; 82 } 83 } 84 return NULL; 85 } 86 87 /// Find the parameter with the given name 88 const domAny* findParam(const char* name) 89 { 90 if (pTechnique) { 91 // search the technique contents for the desired parameter 92 for (S32 iParam = 0; iParam < pTechnique->getContents().getCount(); iParam++) { 93 const domAny* param = daeSafeCast<domAny>(pTechnique->getContents()[iParam]); 94 if (param && !String::compare(param->getElementName(), name)) 95 return param; 96 } 97 } 98 return NULL; 99 } 100 101 /// Get the value of the named parameter (use defaultVal if parameter not found) 102 template<typename T> void get(const char* name, T& value, T defaultVal) 103 { 104 value = defaultVal; 105 if (const domAny* param = findParam(name)) 106 value = convert<T>(param->getValue()); 107 } 108 109 /// Get the value of the named animated parameter (use defaultVal if parameter not found) 110 template<typename T> void get(const char* name, AnimatedElement<T>& value, T defaultVal) 111 { 112 value.defaultVal = defaultVal; 113 if (const domAny* param = findParam(name)) 114 value.element = param; 115 } 116 117public: 118 ColladaExtension() : pTechnique(0) { } 119 virtual ~ColladaExtension() { } 120}; 121 122/// Extensions for the <effect> element (and its children) 123class ColladaExtension_effect : public ColladaExtension 124{ 125 // Cached texture transform 126 F32 lastAnimTime; 127 MatrixF textureTransform; 128 129public: 130 //---------------------------------- 131 // <effect> 132 // MAX3D profile elements 133 bool double_sided; 134 135 //---------------------------------- 136 // <effect>.<profile_COMMON> 137 // GOOGLEEARTH profile elements 138 //bool double_sided; 139 140 //---------------------------------- 141 // <effect>.<profile_COMMON>.<technique>.<blinn/phong/lambert>.<diffuse>.<texture> 142 // MAYA profile elements 143 bool wrapU, wrapV; 144 bool mirrorU, mirrorV; 145 AnimatedFloat coverageU, coverageV; 146 AnimatedFloat translateFrameU, translateFrameV; 147 AnimatedFloat rotateFrame; 148 AnimatedBool stagger; // @todo: not supported yet 149 AnimatedFloat repeatU, repeatV; 150 AnimatedFloat offsetU, offsetV; 151 AnimatedFloat rotateUV; 152 AnimatedFloat noiseU, noiseV; 153 154 //---------------------------------- 155 // <effect>.<profile_COMMON>.<technique> 156 // FCOLLADA profile elements 157 domFx_sampler2D_common_complexType* bumpSampler; 158 159public: 160 ColladaExtension_effect(const domEffect* effect) 161 : lastAnimTime(TSShapeLoader::DefaultTime-1), textureTransform(true), bumpSampler(0) 162 { 163 //---------------------------------- 164 // <effect> 165 // MAX3D profile 166 pTechnique = findExtraTechnique(effect, "MAX3D"); 167 GET_EXTRA_PARAM(double_sided, false); 168 169 //---------------------------------- 170 // <effect>.<profile_COMMON> 171 const domProfile_COMMON* profileCommon = ColladaUtils::findEffectCommonProfile(effect); 172 173 // GOOGLEEARTH profile (same double_sided element) 174 pTechnique = findExtraTechnique(profileCommon, "GOOGLEEARTH"); 175 GET_EXTRA_PARAM(double_sided, double_sided); 176 177 //---------------------------------- 178 // <effect>.<profile_COMMON>.<technique>.<blinn/phong/lambert>.<diffuse>.<texture> 179 const domCommon_color_or_texture_type_complexType* domDiffuse = ColladaUtils::findEffectDiffuse(effect); 180 const domFx_sampler2D_common_complexType* sampler2D = ColladaUtils::getTextureSampler(effect, domDiffuse); 181 182 // Use the sampler2D to set default values for wrap/mirror flags 183 wrapU = wrapV = true; 184 mirrorU = mirrorV = false; 185 if (sampler2D) { 186 domFx_sampler2D_common_complexType::domWrap_s* wrap_s = sampler2D->getWrap_s(); 187 domFx_sampler2D_common_complexType::domWrap_t* wrap_t = sampler2D->getWrap_t(); 188 189 mirrorU = (wrap_s && wrap_s->getValue() == FX_SAMPLER_WRAP_COMMON_MIRROR); 190 wrapU = (mirrorU || !wrap_s || (wrap_s->getValue() == FX_SAMPLER_WRAP_COMMON_WRAP)); 191 mirrorV = (wrap_t && wrap_t->getValue() == FX_SAMPLER_WRAP_COMMON_MIRROR); 192 wrapV = (mirrorV || !wrap_t || (wrap_t->getValue() == FX_SAMPLER_WRAP_COMMON_WRAP)); 193 } 194 195 // MAYA profile 196 pTechnique = findExtraTechnique(domDiffuse ? domDiffuse->getTexture() : 0, "MAYA"); 197 GET_EXTRA_PARAM(wrapU, wrapU); GET_EXTRA_PARAM(wrapV, wrapV); 198 GET_EXTRA_PARAM(mirrorU, mirrorU); GET_EXTRA_PARAM(mirrorV, mirrorV); 199 GET_EXTRA_PARAM(coverageU, 1.0); GET_EXTRA_PARAM(coverageV, 1.0); 200 GET_EXTRA_PARAM(translateFrameU, 0.0); GET_EXTRA_PARAM(translateFrameV, 0.0); 201 GET_EXTRA_PARAM(rotateFrame, 0.0); 202 GET_EXTRA_PARAM(stagger, false); 203 GET_EXTRA_PARAM(repeatU, 1.0); GET_EXTRA_PARAM(repeatV, 1.0); 204 GET_EXTRA_PARAM(offsetU, 0.0); GET_EXTRA_PARAM(offsetV, 0.0); 205 GET_EXTRA_PARAM(rotateUV, 0.0); 206 GET_EXTRA_PARAM(noiseU, 0.0); GET_EXTRA_PARAM(noiseV, 0.0); 207 208 // FCOLLADA profile 209 if (profileCommon) { 210 pTechnique = findExtraTechnique((const domProfile_COMMON::domTechnique*)profileCommon->getTechnique(), "FCOLLADA"); 211 if (pTechnique) { 212 domAny* bump = daeSafeCast<domAny>(const_cast<domTechnique*>(pTechnique)->getChild("bump")); 213 if (bump) { 214 domAny* bumpTexture = daeSafeCast<domAny>(bump->getChild("texture")); 215 if (bumpTexture) { 216 daeSIDResolver resolver(const_cast<domEffect*>(effect), bumpTexture->getAttribute("texture").c_str()); 217 domCommon_newparam_type* param = daeSafeCast<domCommon_newparam_type>(resolver.getElement()); 218 if (param) 219 bumpSampler = param->getSampler2D(); 220 } 221 } 222 } 223 } 224 } 225 226 /// Check if any of the MAYA texture transform elements are animated within 227 /// the interval 228 bool animatesTextureTransform(F32 start, F32 end); 229 230 /// Apply the MAYA texture transform to the given UV coordinates 231 void applyTextureTransform(Point2F& uv, F32 time); 232}; 233 234/// Extensions for the <node> element 235class ColladaExtension_node : public ColladaExtension 236{ 237public: 238 // FCOLLADA or OpenCOLLADA profile elements 239 AnimatedFloat visibility; 240 const char* user_properties; 241 242 ColladaExtension_node(const domNode* node) 243 { 244 // FCOLLADA profile 245 pTechnique = findExtraTechnique(node, "FCOLLADA"); 246 GET_EXTRA_PARAM(visibility, 1.0); 247 GET_EXTRA_PARAM(user_properties, ""); 248 249 // OpenCOLLADA profile 250 pTechnique = findExtraTechnique(node, "OpenCOLLADA"); 251 if (!visibility.element) 252 GET_EXTRA_PARAM(visibility, 1.0); 253 GET_EXTRA_PARAM(user_properties, user_properties); 254 } 255}; 256 257/// Extensions for the <geometry> element 258class ColladaExtension_geometry : public ColladaExtension 259{ 260public: 261 // MAYA profile elements 262 bool double_sided; 263 264 ColladaExtension_geometry(const domGeometry* geometry) 265 { 266 // MAYA profile 267 pTechnique = findExtraTechnique(geometry, "MAYA"); 268 GET_EXTRA_PARAM(double_sided, false); 269 } 270}; 271 272// Extensions for the <animation_clip> element 273class ColladaExtension_animation_clip : public ColladaExtension 274{ 275public: 276 struct Trigger { 277 F32 time; 278 S32 state; 279 }; 280 281 // Torque profile elements (none of these are animatable) 282 S32 num_triggers; 283 Vector<Trigger> triggers; 284 bool cyclic; 285 bool blend; 286 F32 blendReferenceTime; 287 F32 priority; 288 289 ColladaExtension_animation_clip(const domAnimation_clip* clip) 290 { 291 // Torque profile 292 pTechnique = findExtraTechnique(clip, "Torque"); 293 GET_EXTRA_PARAM(num_triggers, 0); 294 for (S32 iTrigger = 0; iTrigger < num_triggers; iTrigger++) { 295 triggers.increment(); 296 get(avar("trigger_time%d", iTrigger), triggers.last().time, 0.0f); 297 get(avar("trigger_state%d", iTrigger), triggers.last().state, 0); 298 } 299 GET_EXTRA_PARAM(cyclic, false); 300 GET_EXTRA_PARAM(blend, false); 301 GET_EXTRA_PARAM(blendReferenceTime, 0.0f); 302 GET_EXTRA_PARAM(priority, 5.0f); 303 } 304}; 305 306#endif // _COLLADA_EXTENSIONS_H_ 307