1 /* 2 Copyright (C) 2010-2014 Kristian Duske 3 4 This file is part of TrenchBroom. 5 6 TrenchBroom is free software: you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 TrenchBroom is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with TrenchBroom. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "ChangeBrushFaceAttributesRequest.h" 21 #include "Macros.h" 22 #include "Model/BrushFace.h" 23 24 #include <cassert> 25 26 namespace TrenchBroom { 27 namespace Model { 28 template <typename T> evaluateValueOp(const T oldValue,const T newValue,const ChangeBrushFaceAttributesRequest::ValueOp op)29 T evaluateValueOp(const T oldValue, const T newValue, const ChangeBrushFaceAttributesRequest::ValueOp op) { 30 switch (op) { 31 case ChangeBrushFaceAttributesRequest::ValueOp_Set: 32 return newValue; 33 case ChangeBrushFaceAttributesRequest::ValueOp_Add: 34 return oldValue + newValue; 35 case ChangeBrushFaceAttributesRequest::ValueOp_Mul: 36 return oldValue * newValue; 37 case ChangeBrushFaceAttributesRequest::ValueOp_None: 38 return oldValue; 39 switchDefault() 40 } 41 } 42 43 template <typename T> evaluateFlagOp(const T oldValue,const T newValue,const ChangeBrushFaceAttributesRequest::FlagOp op)44 T evaluateFlagOp(const T oldValue, const T newValue, const ChangeBrushFaceAttributesRequest::FlagOp op) { 45 switch (op) { 46 case ChangeBrushFaceAttributesRequest::FlagOp_Replace: 47 return newValue; 48 case ChangeBrushFaceAttributesRequest::FlagOp_Set: 49 return oldValue | newValue; 50 case ChangeBrushFaceAttributesRequest::FlagOp_Unset: 51 return oldValue & ~newValue; 52 case ChangeBrushFaceAttributesRequest::FlagOp_None: 53 return oldValue; 54 switchDefault() 55 } 56 } 57 58 bool collateTextureOp(bool& mySet, Assets::Texture*& myTexture, const bool theirSet, Assets::Texture*& theirTexture); collateTextureOp(bool & mySet,Assets::Texture * & myTexture,const bool theirSet,Assets::Texture * & theirTexture)59 bool collateTextureOp(bool& mySet, Assets::Texture*& myTexture, const bool theirSet, Assets::Texture*& theirTexture) { 60 if (mySet) { 61 if (theirSet) { 62 myTexture = theirTexture; 63 return true; 64 } else { 65 return true; 66 } 67 } else { 68 mySet = theirSet; 69 myTexture = theirTexture; 70 return true; 71 } 72 } 73 74 bool collateAxisOp(ChangeBrushFaceAttributesRequest::AxisOp& myOp, const ChangeBrushFaceAttributesRequest::AxisOp theirOp); collateAxisOp(ChangeBrushFaceAttributesRequest::AxisOp & myOp,const ChangeBrushFaceAttributesRequest::AxisOp theirOp)75 bool collateAxisOp(ChangeBrushFaceAttributesRequest::AxisOp& myOp, const ChangeBrushFaceAttributesRequest::AxisOp theirOp) { 76 switch (myOp) { 77 case ChangeBrushFaceAttributesRequest::AxisOp_None: 78 myOp = theirOp; 79 return true; 80 case ChangeBrushFaceAttributesRequest::AxisOp_Reset: 81 case ChangeBrushFaceAttributesRequest::AxisOp_ToParaxial: 82 case ChangeBrushFaceAttributesRequest::AxisOp_ToParallel: 83 switch (theirOp) { 84 case ChangeBrushFaceAttributesRequest::AxisOp_None: 85 return true; 86 case ChangeBrushFaceAttributesRequest::AxisOp_Reset: 87 case ChangeBrushFaceAttributesRequest::AxisOp_ToParallel: 88 case ChangeBrushFaceAttributesRequest::AxisOp_ToParaxial: 89 myOp = theirOp; 90 return true; 91 switchDefault() 92 } 93 switchDefault() 94 }; 95 } 96 97 template <typename T> collateValueOp(ChangeBrushFaceAttributesRequest::ValueOp & myOp,T & myValue,const ChangeBrushFaceAttributesRequest::ValueOp theirOp,const T theirValue)98 bool collateValueOp(ChangeBrushFaceAttributesRequest::ValueOp& myOp, T& myValue, const ChangeBrushFaceAttributesRequest::ValueOp theirOp, const T theirValue) { 99 switch (myOp) { 100 case ChangeBrushFaceAttributesRequest::ValueOp_None: 101 myOp = theirOp; 102 myValue = theirValue; 103 return true; 104 case ChangeBrushFaceAttributesRequest::ValueOp_Set: 105 switch (theirOp) { 106 case ChangeBrushFaceAttributesRequest::ValueOp_None: 107 return true; 108 case ChangeBrushFaceAttributesRequest::ValueOp_Set: 109 myValue = theirValue; 110 return true; 111 case ChangeBrushFaceAttributesRequest::ValueOp_Add: 112 case ChangeBrushFaceAttributesRequest::ValueOp_Mul: 113 return false; 114 switchDefault() 115 } 116 case ChangeBrushFaceAttributesRequest::ValueOp_Add: 117 switch (theirOp) { 118 case ChangeBrushFaceAttributesRequest::ValueOp_None: 119 return true; 120 case ChangeBrushFaceAttributesRequest::ValueOp_Set: 121 myOp = theirOp; 122 myValue = theirValue; 123 return true; 124 case ChangeBrushFaceAttributesRequest::ValueOp_Add: 125 myValue += theirValue; 126 return true; 127 case ChangeBrushFaceAttributesRequest::ValueOp_Mul: 128 return false; 129 switchDefault() 130 } 131 case ChangeBrushFaceAttributesRequest::ValueOp_Mul: 132 switch (theirOp) { 133 case ChangeBrushFaceAttributesRequest::ValueOp_None: 134 return true; 135 case ChangeBrushFaceAttributesRequest::ValueOp_Set: 136 myOp = theirOp; 137 myValue = theirValue; 138 case ChangeBrushFaceAttributesRequest::ValueOp_Add: 139 return false; 140 case ChangeBrushFaceAttributesRequest::ValueOp_Mul: 141 myValue *= theirValue; 142 return true; 143 switchDefault() 144 } 145 switchDefault() 146 } 147 } 148 149 template <typename T> collateFlagOp(ChangeBrushFaceAttributesRequest::FlagOp & myOp,T & myValue,const ChangeBrushFaceAttributesRequest::FlagOp theirOp,const T theirValue)150 bool collateFlagOp(ChangeBrushFaceAttributesRequest::FlagOp& myOp, T& myValue, const ChangeBrushFaceAttributesRequest::FlagOp theirOp, const T theirValue) { 151 switch (myOp) { 152 case ChangeBrushFaceAttributesRequest::FlagOp_None: 153 myOp = theirOp; 154 myValue = theirValue; 155 case ChangeBrushFaceAttributesRequest::FlagOp_Replace: 156 switch (theirOp) { 157 case ChangeBrushFaceAttributesRequest::FlagOp_None: 158 return true; 159 case ChangeBrushFaceAttributesRequest::FlagOp_Replace: 160 myValue = theirValue; 161 return true; 162 case ChangeBrushFaceAttributesRequest::FlagOp_Set: 163 case ChangeBrushFaceAttributesRequest::FlagOp_Unset: 164 return false; 165 switchDefault() 166 } 167 case ChangeBrushFaceAttributesRequest::FlagOp_Set: 168 switch (theirOp) { 169 case ChangeBrushFaceAttributesRequest::FlagOp_None: 170 return true; 171 case ChangeBrushFaceAttributesRequest::FlagOp_Replace: 172 myOp = theirOp; 173 myValue = theirValue; 174 return true; 175 case ChangeBrushFaceAttributesRequest::FlagOp_Set: 176 myValue |= theirValue; 177 return true; 178 case ChangeBrushFaceAttributesRequest::FlagOp_Unset: 179 return false; 180 switchDefault() 181 } 182 case ChangeBrushFaceAttributesRequest::FlagOp_Unset: 183 switch (theirOp) { 184 case ChangeBrushFaceAttributesRequest::FlagOp_None: 185 return true; 186 case ChangeBrushFaceAttributesRequest::FlagOp_Replace: 187 myOp = theirOp; 188 myValue = theirValue; 189 return true; 190 case ChangeBrushFaceAttributesRequest::FlagOp_Set: 191 return false; 192 case ChangeBrushFaceAttributesRequest::FlagOp_Unset: 193 myValue |= theirValue; 194 return true; 195 switchDefault() 196 } 197 switchDefault() 198 } 199 } 200 ChangeBrushFaceAttributesRequest()201 ChangeBrushFaceAttributesRequest::ChangeBrushFaceAttributesRequest() : 202 m_texture(NULL), 203 m_xOffset(0.0f), 204 m_yOffset(0.0f), 205 m_rotation(0.0f), 206 m_xScale(0.0f), 207 m_yScale(0.0f), 208 m_surfaceFlags(0), 209 m_contentFlags(0), 210 m_surfaceValue(0.0f), 211 m_setTexture(false), 212 m_axisOp(AxisOp_None), 213 m_xOffsetOp(ValueOp_None), 214 m_yOffsetOp(ValueOp_None), 215 m_rotationOp(ValueOp_None), 216 m_xScaleOp(ValueOp_None), 217 m_yScaleOp(ValueOp_None), 218 m_surfaceFlagsOp(FlagOp_None), 219 m_contentFlagsOp(FlagOp_None), 220 m_surfaceValueOp(ValueOp_None) {} 221 clear()222 void ChangeBrushFaceAttributesRequest::clear() { 223 m_texture = NULL; 224 m_xOffset = m_yOffset = 0.0f; 225 m_rotation = 0.0f; 226 m_xScale = m_yScale = 1.0f; 227 m_surfaceFlags = m_contentFlags = 0; 228 m_surfaceValue = 0.0f; 229 m_setTexture = false; 230 m_axisOp = AxisOp_None; 231 m_xOffsetOp = m_yOffsetOp = ValueOp_None; 232 m_rotationOp = ValueOp_None; 233 m_xScaleOp = m_yScaleOp = ValueOp_None; 234 m_surfaceFlagsOp = m_contentFlagsOp = FlagOp_None; 235 m_surfaceValueOp = ValueOp_None; 236 } 237 name() const238 const String ChangeBrushFaceAttributesRequest::name() const { 239 return "Change Face Attributes"; 240 } 241 evaluate(const BrushFaceList & faces) const242 void ChangeBrushFaceAttributesRequest::evaluate(const BrushFaceList& faces) const { 243 BrushFaceList::const_iterator it, end; 244 for (it = faces.begin(), end = faces.end(); it != end; ++it) { 245 BrushFace* face = *it; 246 if (m_setTexture) 247 face->setTexture(m_texture); 248 249 switch (m_axisOp) { 250 case AxisOp_Reset: 251 face->resetTextureAxes(); 252 break; 253 case AxisOp_None: 254 case AxisOp_ToParaxial: 255 case AxisOp_ToParallel: 256 break; 257 switchDefault() 258 } 259 260 face->setXOffset(evaluateValueOp(face->xOffset(), m_xOffset, m_xOffsetOp)); 261 face->setYOffset(evaluateValueOp(face->yOffset(), m_yOffset, m_yOffsetOp)); 262 face->setRotation(evaluateValueOp(face->rotation(), m_rotation, m_rotationOp)); 263 face->setXScale(evaluateValueOp(face->xScale(), m_xScale, m_xScaleOp)); 264 face->setYScale(evaluateValueOp(face->yScale(), m_yScale, m_yScaleOp)); 265 face->setSurfaceFlags(evaluateFlagOp(face->surfaceFlags(), m_surfaceFlags, m_surfaceFlagsOp)); 266 face->setSurfaceContents(evaluateFlagOp(face->surfaceContents(), m_contentFlags, m_contentFlagsOp)); 267 face->setSurfaceValue(evaluateValueOp(face->surfaceValue(), m_surfaceValue, m_surfaceValueOp)); 268 } 269 } 270 setTexture(Assets::Texture * texture)271 void ChangeBrushFaceAttributesRequest::setTexture(Assets::Texture* texture) { 272 m_texture = texture; 273 m_setTexture = true; 274 } 275 resetTextureAxes()276 void ChangeBrushFaceAttributesRequest::resetTextureAxes() { 277 m_axisOp = AxisOp_Reset; 278 } 279 resetTextureAxesToParaxial()280 void ChangeBrushFaceAttributesRequest::resetTextureAxesToParaxial() { 281 m_axisOp = AxisOp_ToParaxial; 282 } 283 resetTextureAxesToParallel()284 void ChangeBrushFaceAttributesRequest::resetTextureAxesToParallel() { 285 m_axisOp = AxisOp_ToParallel; 286 } 287 setOffset(const Vec2f & offset)288 void ChangeBrushFaceAttributesRequest::setOffset(const Vec2f& offset) { 289 setXOffset(offset.x()); 290 setYOffset(offset.y()); 291 } 292 addOffset(const Vec2f & offset)293 void ChangeBrushFaceAttributesRequest::addOffset(const Vec2f& offset) { 294 addXOffset(offset.x()); 295 addYOffset(offset.y()); 296 } 297 mulOffset(const Vec2f & offset)298 void ChangeBrushFaceAttributesRequest::mulOffset(const Vec2f& offset) { 299 mulXOffset(offset.x()); 300 mulYOffset(offset.y()); 301 } 302 setXOffset(const float xOffset)303 void ChangeBrushFaceAttributesRequest::setXOffset(const float xOffset) { 304 m_xOffset = xOffset; 305 m_xOffsetOp = ValueOp_Set; 306 } 307 addXOffset(const float xOffset)308 void ChangeBrushFaceAttributesRequest::addXOffset(const float xOffset) { 309 m_xOffset = xOffset; 310 m_xOffsetOp = ValueOp_Add; 311 } 312 mulXOffset(const float xOffset)313 void ChangeBrushFaceAttributesRequest::mulXOffset(const float xOffset) { 314 m_xOffset = xOffset; 315 m_xOffsetOp = ValueOp_Mul; 316 } 317 setYOffset(const float yOffset)318 void ChangeBrushFaceAttributesRequest::setYOffset(const float yOffset) { 319 m_yOffset = yOffset; 320 m_yOffsetOp = ValueOp_Set; 321 } 322 addYOffset(const float yOffset)323 void ChangeBrushFaceAttributesRequest::addYOffset(const float yOffset) { 324 m_yOffset = yOffset; 325 m_yOffsetOp = ValueOp_Add; 326 } 327 mulYOffset(const float yOffset)328 void ChangeBrushFaceAttributesRequest::mulYOffset(const float yOffset) { 329 m_yOffset = yOffset; 330 m_yOffsetOp = ValueOp_Mul; 331 } 332 setRotation(const float rotation)333 void ChangeBrushFaceAttributesRequest::setRotation(const float rotation) { 334 m_rotation = rotation; 335 m_rotationOp = ValueOp_Set; 336 } 337 addRotation(const float rotation)338 void ChangeBrushFaceAttributesRequest::addRotation(const float rotation) { 339 m_rotation = rotation; 340 m_rotationOp = ValueOp_Add; 341 } 342 mulRotation(const float rotation)343 void ChangeBrushFaceAttributesRequest::mulRotation(const float rotation) { 344 m_rotation = rotation; 345 m_rotationOp = ValueOp_Mul; 346 } 347 setScale(const Vec2f & scale)348 void ChangeBrushFaceAttributesRequest::setScale(const Vec2f& scale) { 349 setXScale(scale.x()); 350 setYScale(scale.y()); 351 } 352 addScale(const Vec2f & scale)353 void ChangeBrushFaceAttributesRequest::addScale(const Vec2f& scale) { 354 addXScale(scale.x()); 355 addYScale(scale.y()); 356 } 357 mulScale(const Vec2f & scale)358 void ChangeBrushFaceAttributesRequest::mulScale(const Vec2f& scale) { 359 mulXScale(scale.x()); 360 mulYScale(scale.y()); 361 } 362 setXScale(const float xScale)363 void ChangeBrushFaceAttributesRequest::setXScale(const float xScale) { 364 m_xScale = xScale; 365 m_xScaleOp = ValueOp_Set; 366 } 367 addXScale(const float xScale)368 void ChangeBrushFaceAttributesRequest::addXScale(const float xScale) { 369 m_xScale = xScale; 370 m_xScaleOp = ValueOp_Add; 371 } 372 mulXScale(const float xScale)373 void ChangeBrushFaceAttributesRequest::mulXScale(const float xScale) { 374 m_xScale = xScale; 375 m_xScaleOp = ValueOp_Mul; 376 } 377 setYScale(const float yScale)378 void ChangeBrushFaceAttributesRequest::setYScale(const float yScale) { 379 m_yScale = yScale; 380 m_yScaleOp = ValueOp_Set; 381 } 382 addYScale(const float yScale)383 void ChangeBrushFaceAttributesRequest::addYScale(const float yScale) { 384 m_yScale = yScale; 385 m_yScaleOp = ValueOp_Add; 386 } 387 mulYScale(const float yScale)388 void ChangeBrushFaceAttributesRequest::mulYScale(const float yScale) { 389 m_yScale = yScale; 390 m_yScaleOp = ValueOp_Mul; 391 } 392 replaceSurfaceFlags(const int surfaceFlags)393 void ChangeBrushFaceAttributesRequest::replaceSurfaceFlags(const int surfaceFlags) { 394 m_surfaceFlags = surfaceFlags; 395 m_surfaceFlagsOp = FlagOp_Replace; 396 } 397 setSurfaceFlag(const size_t surfaceFlag)398 void ChangeBrushFaceAttributesRequest::setSurfaceFlag(const size_t surfaceFlag) { 399 assert(surfaceFlag < sizeof(int) * 8); 400 m_surfaceFlags = (1 << surfaceFlag); 401 m_surfaceFlagsOp = FlagOp_Set; 402 } 403 unsetSurfaceFlag(const size_t surfaceFlag)404 void ChangeBrushFaceAttributesRequest::unsetSurfaceFlag(const size_t surfaceFlag) { 405 assert(surfaceFlag < sizeof(int) * 8); 406 m_surfaceFlags = (1 << surfaceFlag); 407 m_surfaceFlagsOp = FlagOp_Unset; 408 } 409 replaceContentFlags(const int contentFlags)410 void ChangeBrushFaceAttributesRequest::replaceContentFlags(const int contentFlags) { 411 m_contentFlags = contentFlags; 412 m_contentFlagsOp = FlagOp_Replace; 413 } 414 setContentFlag(const size_t contentFlag)415 void ChangeBrushFaceAttributesRequest::setContentFlag(const size_t contentFlag) { 416 assert(contentFlag < sizeof(int) * 8); 417 m_contentFlags = (1 << contentFlag); 418 m_contentFlagsOp = FlagOp_Set; 419 } 420 unsetContentFlag(const size_t contentFlag)421 void ChangeBrushFaceAttributesRequest::unsetContentFlag(const size_t contentFlag) { 422 assert(contentFlag < sizeof(int) * 8); 423 m_contentFlags = (1 << contentFlag); 424 m_contentFlagsOp = FlagOp_Unset; 425 } 426 setSurfaceValue(const float surfaceValue)427 void ChangeBrushFaceAttributesRequest::setSurfaceValue(const float surfaceValue) { 428 m_surfaceValue = surfaceValue; 429 m_surfaceValueOp = ValueOp_Set; 430 } 431 addSurfaceValue(const float surfaceValue)432 void ChangeBrushFaceAttributesRequest::addSurfaceValue(const float surfaceValue) { 433 m_surfaceValue = surfaceValue; 434 m_surfaceValueOp = ValueOp_Add; 435 } 436 mulSurfaceValue(const float surfaceValue)437 void ChangeBrushFaceAttributesRequest::mulSurfaceValue(const float surfaceValue) { 438 m_surfaceValue = surfaceValue; 439 m_surfaceValueOp = ValueOp_Mul; 440 } 441 setAll(const Model::BrushFace * face)442 void ChangeBrushFaceAttributesRequest::setAll(const Model::BrushFace* face) { 443 setAll(face->attribs()); 444 } 445 setAll(const Model::BrushFaceAttributes & attributes)446 void ChangeBrushFaceAttributesRequest::setAll(const Model::BrushFaceAttributes& attributes) { 447 setTexture(attributes.texture()); 448 setXOffset(attributes.xOffset()); 449 setYOffset(attributes.yOffset()); 450 setRotation(attributes.rotation()); 451 setXScale(attributes.xScale()); 452 setYScale(attributes.yScale()); 453 replaceSurfaceFlags(attributes.surfaceFlags()); 454 replaceContentFlags(attributes.surfaceContents()); 455 setSurfaceValue(attributes.surfaceValue()); 456 } 457 collateWith(ChangeBrushFaceAttributesRequest & other)458 bool ChangeBrushFaceAttributesRequest::collateWith(ChangeBrushFaceAttributesRequest& other) { 459 Assets::Texture* newTexture = m_texture; bool newSetTexture = m_setTexture; 460 AxisOp newAxisOp = m_axisOp; 461 462 float newXOffset = m_xOffset; ValueOp newXOffsetOp = m_xOffsetOp; 463 float newYOffset = m_yOffset; ValueOp newYOffsetOp = m_yOffsetOp; 464 float newRotation = m_rotation; ValueOp newRotationOp = m_rotationOp; 465 float newXScale = m_xScale; ValueOp newXScaleOp = m_xScaleOp; 466 float newYScale = m_yScale; ValueOp newYScaleOp = m_yScaleOp; 467 468 int newSurfaceFlags = m_surfaceFlags; FlagOp newSurfaceFlagsOp = m_surfaceFlagsOp; 469 int newContentFlags = m_contentFlags; FlagOp newContentFlagsOp = m_contentFlagsOp; 470 float newSurfaceValue = m_surfaceValue; ValueOp newSurfaceValueOp = m_surfaceValueOp; 471 472 if (!collateAxisOp(newAxisOp, other.m_axisOp)) 473 return false; 474 if (!collateTextureOp(newSetTexture, newTexture, other.m_setTexture, other.m_texture)) 475 return false; 476 if (!collateValueOp(newXOffsetOp, newXOffset, other.m_xOffsetOp, other.m_xOffset)) 477 return false; 478 if (!collateValueOp(newYOffsetOp, newYOffset, other.m_yOffsetOp, other.m_yOffset)) 479 return false; 480 if (!collateValueOp(newRotationOp, newRotation, other.m_rotationOp, other.m_rotation)) 481 return false; 482 if (!collateValueOp(newXScaleOp, newXScale, other.m_xScaleOp, other.m_xScale)) 483 return false; 484 if (!collateValueOp(newYScaleOp, newYScale, other.m_yScaleOp, other.m_yScale)) 485 return false; 486 487 if (!collateFlagOp(newSurfaceFlagsOp, newSurfaceFlags, other.m_surfaceFlagsOp, other.m_surfaceFlags)) 488 return false; 489 if (!collateFlagOp(newContentFlagsOp, newContentFlags, other.m_contentFlagsOp, other.m_contentFlags)) 490 return false; 491 if (!collateValueOp(newSurfaceValueOp, newSurfaceValue, other.m_surfaceValueOp, other.m_surfaceValue)) 492 return false; 493 494 m_texture = newTexture; m_setTexture = newSetTexture; 495 m_axisOp = newAxisOp; 496 m_xOffset = newXOffset; m_xOffsetOp = newXOffsetOp; 497 m_yOffset = newYOffset; m_yOffsetOp = newYOffsetOp; 498 m_rotation = newRotation; m_rotationOp = newRotationOp; 499 m_xScale = newXScale; m_xScaleOp = newXScaleOp; 500 m_yScale = newYScale; m_yScaleOp = newYScaleOp; 501 502 m_surfaceFlags = newSurfaceFlags; m_surfaceFlagsOp = newSurfaceFlagsOp; 503 m_contentFlags = newContentFlags; m_contentFlagsOp = newContentFlagsOp; 504 m_surfaceValue = newSurfaceValue; m_surfaceValueOp = newSurfaceValueOp; 505 506 return true; 507 } 508 } 509 } 510