1 // Copyright (C) 2002-2012 Nikolaus Gebhardt 2 // This file is part of the "Irrlicht Engine". 3 // For conditions of distribution and use, see copyright notice in irrlicht.h 4 5 #include "CAttributes.h" 6 #include "fast_atof.h" 7 #include "ITexture.h" 8 #include "IVideoDriver.h" 9 10 namespace irr 11 { 12 namespace io 13 { 14 15 /* 16 basic types 17 */ 18 19 // Attribute implemented for boolean values 20 class CBoolAttribute : public IAttribute 21 { 22 public: 23 CBoolAttribute(const char * name,bool value)24 CBoolAttribute(const char* name, bool value) 25 { 26 Name = name; 27 setBool(value); 28 } 29 getInt()30 virtual s32 getInt() 31 { 32 return BoolValue ? 1 : 0; 33 } 34 getFloat()35 virtual f32 getFloat() 36 { 37 return BoolValue ? 1.0f : 0.0f; 38 } 39 getBool()40 virtual bool getBool() 41 { 42 return BoolValue; 43 } 44 getStringW()45 virtual core::stringw getStringW() 46 { 47 return core::stringw( BoolValue ? L"true" : L"false" ); 48 } 49 setInt(s32 intValue)50 virtual void setInt(s32 intValue) 51 { 52 BoolValue = (intValue != 0); 53 } 54 setFloat(f32 floatValue)55 virtual void setFloat(f32 floatValue) 56 { 57 BoolValue = (floatValue != 0); 58 } 59 setBool(bool boolValue)60 virtual void setBool(bool boolValue) 61 { 62 BoolValue = boolValue; 63 } 64 setString(const char * string)65 virtual void setString(const char* string) 66 { 67 BoolValue = strcmp(string, "true") == 0; 68 } 69 getType()70 virtual E_ATTRIBUTE_TYPE getType() const 71 { 72 return EAT_BOOL; 73 } 74 getTypeString()75 virtual const wchar_t* getTypeString() const 76 { 77 return L"bool"; 78 } 79 80 bool BoolValue; 81 }; 82 83 // Attribute implemented for integers 84 class CIntAttribute : public IAttribute 85 { 86 public: 87 CIntAttribute(const char * name,s32 value)88 CIntAttribute(const char* name, s32 value) 89 { 90 Name = name; 91 setInt(value); 92 } 93 getInt()94 virtual s32 getInt() 95 { 96 return Value; 97 } 98 getFloat()99 virtual f32 getFloat() 100 { 101 return (f32)Value; 102 } 103 getBool()104 virtual bool getBool() 105 { 106 return (Value != 0); 107 } 108 getStringW()109 virtual core::stringw getStringW() 110 { 111 return core::stringw(Value); 112 } 113 setInt(s32 intValue)114 virtual void setInt(s32 intValue) 115 { 116 Value = intValue; 117 } 118 setFloat(f32 floatValue)119 virtual void setFloat(f32 floatValue) 120 { 121 Value = (s32)floatValue; 122 }; 123 setString(const char * text)124 virtual void setString(const char* text) 125 { 126 Value = atoi(text); 127 } 128 getType()129 virtual E_ATTRIBUTE_TYPE getType() const 130 { 131 return EAT_INT; 132 } 133 134 getTypeString()135 virtual const wchar_t* getTypeString() const 136 { 137 return L"int"; 138 } 139 140 s32 Value; 141 }; 142 143 // Attribute implemented for floats 144 class CFloatAttribute : public IAttribute 145 { 146 public: 147 CFloatAttribute(const char * name,f32 value)148 CFloatAttribute(const char* name, f32 value) 149 { 150 Name = name; 151 setFloat(value); 152 } 153 getInt()154 virtual s32 getInt() 155 { 156 return (s32)Value; 157 } 158 getFloat()159 virtual f32 getFloat() 160 { 161 return Value; 162 } 163 getBool()164 virtual bool getBool() 165 { 166 return (Value != 0); 167 } 168 getStringW()169 virtual core::stringw getStringW() 170 { 171 return core::stringw((double)Value); 172 } 173 setInt(s32 intValue)174 virtual void setInt(s32 intValue) 175 { 176 Value = (f32)intValue; 177 } 178 setFloat(f32 floatValue)179 virtual void setFloat(f32 floatValue) 180 { 181 Value = floatValue; 182 } 183 setString(const char * text)184 virtual void setString(const char* text) 185 { 186 Value = core::fast_atof(text); 187 } 188 getType()189 virtual E_ATTRIBUTE_TYPE getType() const 190 { 191 return EAT_FLOAT; 192 } 193 194 getTypeString()195 virtual const wchar_t* getTypeString() const 196 { 197 return L"float"; 198 } 199 200 f32 Value; 201 }; 202 203 204 205 /* 206 Types which can be represented as a list of numbers 207 */ 208 209 // Base class for all attributes which are a list of numbers- 210 // vectors, colors, positions, triangles, etc 211 class CNumbersAttribute : public IAttribute 212 { 213 public: 214 CNumbersAttribute(const char * name,video::SColorf value)215 CNumbersAttribute(const char* name, video::SColorf value) : 216 ValueI(), ValueF(), Count(4), IsFloat(true) 217 { 218 Name = name; 219 ValueF.push_back(value.r); 220 ValueF.push_back(value.g); 221 ValueF.push_back(value.b); 222 ValueF.push_back(value.a); 223 } 224 CNumbersAttribute(const char * name,video::SColor value)225 CNumbersAttribute(const char* name, video::SColor value) : 226 ValueI(), ValueF(), Count(4), IsFloat(false) 227 { 228 Name = name; 229 ValueI.push_back(value.getRed()); 230 ValueI.push_back(value.getGreen()); 231 ValueI.push_back(value.getBlue()); 232 ValueI.push_back(value.getAlpha()); 233 } 234 235 CNumbersAttribute(const char * name,core::vector3df value)236 CNumbersAttribute(const char* name, core::vector3df value) : 237 ValueI(), ValueF(), Count(3), IsFloat(true) 238 { 239 Name = name; 240 ValueF.push_back(value.X); 241 ValueF.push_back(value.Y); 242 ValueF.push_back(value.Z); 243 } 244 CNumbersAttribute(const char * name,core::rect<s32> value)245 CNumbersAttribute(const char* name, core::rect<s32> value) : 246 ValueI(), ValueF(), Count(4), IsFloat(false) 247 { 248 Name = name; 249 ValueI.push_back(value.UpperLeftCorner.X); 250 ValueI.push_back(value.UpperLeftCorner.Y); 251 ValueI.push_back(value.LowerRightCorner.X); 252 ValueI.push_back(value.LowerRightCorner.Y); 253 } 254 CNumbersAttribute(const char * name,core::rect<f32> value)255 CNumbersAttribute(const char* name, core::rect<f32> value) : 256 ValueI(), ValueF(), Count(4), IsFloat(true) 257 { 258 Name = name; 259 ValueF.push_back(value.UpperLeftCorner.X); 260 ValueF.push_back(value.UpperLeftCorner.Y); 261 ValueF.push_back(value.LowerRightCorner.X); 262 ValueF.push_back(value.LowerRightCorner.Y); 263 } 264 CNumbersAttribute(const char * name,core::matrix4 value)265 CNumbersAttribute(const char* name, core::matrix4 value) : 266 ValueI(), ValueF(), Count(16), IsFloat(true) 267 { 268 Name = name; 269 for (s32 r=0; r<4; ++r) 270 for (s32 c=0; c<4; ++c) 271 ValueF.push_back(value(r,c)); 272 } 273 CNumbersAttribute(const char * name,core::quaternion value)274 CNumbersAttribute(const char* name, core::quaternion value) : 275 ValueI(), ValueF(), Count(4), IsFloat(true) 276 { 277 Name = name; 278 ValueF.push_back(value.X); 279 ValueF.push_back(value.Y); 280 ValueF.push_back(value.Z); 281 ValueF.push_back(value.W); 282 } 283 CNumbersAttribute(const char * name,core::aabbox3d<f32> value)284 CNumbersAttribute(const char* name, core::aabbox3d<f32> value) : 285 ValueI(), ValueF(), Count(6), IsFloat(true) 286 { 287 Name = name; 288 ValueF.push_back(value.MinEdge.X); 289 ValueF.push_back(value.MinEdge.Y); 290 ValueF.push_back(value.MinEdge.Z); 291 ValueF.push_back(value.MaxEdge.X); 292 ValueF.push_back(value.MaxEdge.Y); 293 ValueF.push_back(value.MaxEdge.Z); 294 } 295 CNumbersAttribute(const char * name,core::plane3df value)296 CNumbersAttribute(const char* name, core::plane3df value) : 297 ValueI(), ValueF(), Count(4), IsFloat(true) 298 { 299 Name = name; 300 ValueF.push_back(value.Normal.X); 301 ValueF.push_back(value.Normal.Y); 302 ValueF.push_back(value.Normal.Z); 303 ValueF.push_back(value.D); 304 } 305 CNumbersAttribute(const char * name,core::triangle3df value)306 CNumbersAttribute(const char* name, core::triangle3df value) : 307 ValueI(), ValueF(), Count(9), IsFloat(true) 308 { 309 Name = name; 310 ValueF.push_back(value.pointA.X); 311 ValueF.push_back(value.pointA.Y); 312 ValueF.push_back(value.pointA.Z); 313 ValueF.push_back(value.pointB.X); 314 ValueF.push_back(value.pointB.Y); 315 ValueF.push_back(value.pointB.Z); 316 ValueF.push_back(value.pointC.X); 317 ValueF.push_back(value.pointC.Y); 318 ValueF.push_back(value.pointC.Z); 319 } 320 CNumbersAttribute(const char * name,core::vector2df value)321 CNumbersAttribute(const char* name, core::vector2df value) : 322 ValueI(), ValueF(), Count(2), IsFloat(true) 323 { 324 Name = name; 325 ValueF.push_back(value.X); 326 ValueF.push_back(value.Y); 327 } 328 CNumbersAttribute(const char * name,core::vector2di value)329 CNumbersAttribute(const char* name, core::vector2di value) : 330 ValueI(), ValueF(), Count(2), IsFloat(false) 331 { 332 Name = name; 333 ValueI.push_back(value.X); 334 ValueI.push_back(value.Y); 335 } 336 CNumbersAttribute(const char * name,core::line2di value)337 CNumbersAttribute(const char* name, core::line2di value) : 338 ValueI(), ValueF(), Count(4), IsFloat(false) 339 { 340 Name = name; 341 ValueI.push_back(value.start.X); 342 ValueI.push_back(value.start.Y); 343 ValueI.push_back(value.end.X); 344 ValueI.push_back(value.end.Y); 345 } 346 CNumbersAttribute(const char * name,core::line2df value)347 CNumbersAttribute(const char* name, core::line2df value) : 348 ValueI(), ValueF(), Count(4), IsFloat(true) 349 { 350 Name = name; 351 ValueF.push_back(value.start.X); 352 ValueF.push_back(value.start.Y); 353 ValueF.push_back(value.end.X); 354 ValueF.push_back(value.end.Y); 355 } 356 CNumbersAttribute(const char * name,core::line3df value)357 CNumbersAttribute(const char* name, core::line3df value) : 358 ValueI(), ValueF(), Count(6), IsFloat(true) 359 { 360 Name = name; 361 ValueF.push_back(value.start.X); 362 ValueF.push_back(value.start.Y); 363 ValueF.push_back(value.start.Z); 364 ValueF.push_back(value.end.X); 365 ValueF.push_back(value.end.Y); 366 ValueF.push_back(value.end.Z); 367 } 368 CNumbersAttribute(const char * name,core::dimension2du value)369 CNumbersAttribute(const char* name, core::dimension2du value) : 370 ValueI(), ValueF(), Count(2), IsFloat(false) 371 { 372 Name = name; 373 ValueI.push_back(value.Width); 374 ValueI.push_back(value.Height); 375 } 376 377 CNumbersAttribute(const char * name,core::dimension2df value)378 CNumbersAttribute(const char* name, core::dimension2df value) : 379 ValueI(), ValueF(), Count(2), IsFloat(true) 380 { 381 Name = name; 382 ValueF.push_back(value.Width); 383 ValueF.push_back(value.Height); 384 } 385 386 387 388 // getting values getInt()389 virtual s32 getInt() 390 { 391 if (Count==0) 392 return 0; 393 394 if (IsFloat) 395 return (s32)ValueF[0]; 396 else 397 return ValueI[0]; 398 } 399 getFloat()400 virtual f32 getFloat() 401 { 402 if (Count==0) 403 return 0.0f; 404 405 if (IsFloat) 406 return ValueF[0]; 407 else 408 return (f32)ValueI[0]; 409 } 410 getBool()411 virtual bool getBool() 412 { 413 // return true if any number is nonzero 414 bool ret=false; 415 416 for (u32 i=0; i < Count; ++i) 417 if ( IsFloat ? (ValueF[i] != 0) : (ValueI[i] != 0) ) 418 { 419 ret=true; 420 break; 421 } 422 423 return ret; 424 425 } 426 427 getString()428 virtual core::stringc getString() 429 { 430 core::stringc outstr; 431 432 for (u32 i=0; i <Count; ++i) 433 { 434 if (IsFloat) 435 outstr += ValueF[i]; 436 else 437 outstr += ValueI[i]; 438 439 if (i < Count-1) 440 outstr += ", "; 441 } 442 return outstr; 443 } getStringW()444 virtual core::stringw getStringW() 445 { 446 core::stringw outstr; 447 448 for (u32 i=0; i <Count; ++i) 449 { 450 if (IsFloat) 451 outstr += ValueF[i]; 452 else 453 outstr += ValueI[i]; 454 455 if (i < Count-1) 456 outstr += L", "; 457 } 458 return outstr; 459 } 460 getPosition()461 virtual core::position2di getPosition() 462 { 463 core::position2di p; 464 465 if (IsFloat) 466 { 467 p.X = (s32)(Count > 0 ? ValueF[0] : 0); 468 p.Y = (s32)(Count > 1 ? ValueF[1] : 0); 469 } 470 else 471 { 472 p.X = Count > 0 ? ValueI[0] : 0; 473 p.Y = Count > 1 ? ValueI[1] : 0; 474 } 475 476 return p; 477 } 478 getVector()479 virtual core::vector3df getVector() 480 { 481 core::vector3df v; 482 483 if (IsFloat) 484 { 485 v.X = Count > 0 ? ValueF[0] : 0; 486 v.Y = Count > 1 ? ValueF[1] : 0; 487 v.Z = Count > 2 ? ValueF[2] : 0; 488 } 489 else 490 { 491 v.X = (f32)(Count > 0 ? ValueI[0] : 0); 492 v.Y = (f32)(Count > 1 ? ValueI[1] : 0); 493 v.Z = (f32)(Count > 2 ? ValueI[2] : 0); 494 } 495 496 return v; 497 } 498 getVector2d()499 virtual core::vector2df getVector2d() 500 { 501 core::vector2df v; 502 503 if (IsFloat) 504 { 505 v.X = Count > 0 ? ValueF[0] : 0; 506 v.Y = Count > 1 ? ValueF[1] : 0; 507 } 508 else 509 { 510 v.X = (f32)(Count > 0 ? ValueI[0] : 0); 511 v.Y = (f32)(Count > 1 ? ValueI[1] : 0); 512 } 513 514 return v; 515 } 516 getColorf()517 virtual video::SColorf getColorf() 518 { 519 video::SColorf c; 520 if (IsFloat) 521 { 522 c.setColorComponentValue(0, Count > 0 ? ValueF[0] : 0); 523 c.setColorComponentValue(1, Count > 1 ? ValueF[1] : 0); 524 c.setColorComponentValue(2, Count > 2 ? ValueF[2] : 0); 525 c.setColorComponentValue(3, Count > 3 ? ValueF[3] : 0); 526 } 527 else 528 { 529 c.setColorComponentValue(0, Count > 0 ? (f32)(ValueI[0]) / 255.0f : 0); 530 c.setColorComponentValue(1, Count > 1 ? (f32)(ValueI[1]) / 255.0f : 0); 531 c.setColorComponentValue(2, Count > 2 ? (f32)(ValueI[2]) / 255.0f : 0); 532 c.setColorComponentValue(3, Count > 3 ? (f32)(ValueI[3]) / 255.0f : 0); 533 } 534 535 return c; 536 } 537 getColor()538 virtual video::SColor getColor() 539 { 540 return getColorf().toSColor(); 541 } 542 543 getRect()544 virtual core::rect<s32> getRect() 545 { 546 core::rect<s32> r; 547 548 if (IsFloat) 549 { 550 r.UpperLeftCorner.X = (s32)(Count > 0 ? ValueF[0] : 0); 551 r.UpperLeftCorner.Y = (s32)(Count > 1 ? ValueF[1] : 0); 552 r.LowerRightCorner.X = (s32)(Count > 2 ? ValueF[2] : r.UpperLeftCorner.X); 553 r.LowerRightCorner.Y = (s32)(Count > 3 ? ValueF[3] : r.UpperLeftCorner.Y); 554 } 555 else 556 { 557 r.UpperLeftCorner.X = Count > 0 ? ValueI[0] : 0; 558 r.UpperLeftCorner.Y = Count > 1 ? ValueI[1] : 0; 559 r.LowerRightCorner.X = Count > 2 ? ValueI[2] : r.UpperLeftCorner.X; 560 r.LowerRightCorner.Y = Count > 3 ? ValueI[3] : r.UpperLeftCorner.Y; 561 } 562 return r; 563 } 564 getDimension2d()565 virtual core::dimension2du getDimension2d() 566 { 567 core::dimension2d<u32> dim; 568 569 if (IsFloat) 570 { 571 dim.Width = (u32)(Count > 0 ? ValueF[0] : 0); 572 dim.Height = (u32)(Count > 1 ? ValueF[1] : 0); 573 } 574 else 575 { 576 dim.Width = (u32)(Count > 0 ? ValueI[0] : 0); 577 dim.Height = (u32)(Count > 1 ? ValueI[1] : 0); 578 } 579 return dim; 580 } 581 getMatrix()582 virtual core::matrix4 getMatrix() 583 { 584 core::matrix4 ret; 585 if (IsFloat) 586 { 587 for (u32 r=0; r<4; ++r) 588 for (u32 c=0; c<4; ++c) 589 if (Count > c+r*4) 590 ret(r,c) = ValueF[c+r*4]; 591 } 592 else 593 { 594 for (u32 r=0; r<4; ++r) 595 for (u32 c=0; c<4; ++c) 596 if (Count > c+r*4) 597 ret(r,c) = (f32)ValueI[c+r*4]; 598 } 599 return ret; 600 } 601 getQuaternion()602 virtual core::quaternion getQuaternion() 603 { 604 core::quaternion ret; 605 if (IsFloat) 606 { 607 ret.X = Count > 0 ? ValueF[0] : 0.0f; 608 ret.Y = Count > 1 ? ValueF[1] : 0.0f; 609 ret.Z = Count > 2 ? ValueF[2] : 0.0f; 610 ret.W = Count > 3 ? ValueF[3] : 0.0f; 611 } 612 else 613 { 614 ret.X = Count > 0 ? (f32)ValueI[0] : 0.0f; 615 ret.Y = Count > 1 ? (f32)ValueI[1] : 0.0f; 616 ret.Z = Count > 2 ? (f32)ValueI[2] : 0.0f; 617 ret.W = Count > 3 ? (f32)ValueI[3] : 0.0f; 618 } 619 return ret; 620 } 621 getTriangle()622 virtual core::triangle3df getTriangle() 623 { 624 core::triangle3df ret; 625 626 if (IsFloat) 627 { 628 ret.pointA.X = Count > 0 ? ValueF[0] : 0.0f; 629 ret.pointA.Y = Count > 1 ? ValueF[1] : 0.0f; 630 ret.pointA.Z = Count > 2 ? ValueF[2] : 0.0f; 631 ret.pointB.X = Count > 3 ? ValueF[3] : 0.0f; 632 ret.pointB.Y = Count > 4 ? ValueF[4] : 0.0f; 633 ret.pointB.Z = Count > 5 ? ValueF[5] : 0.0f; 634 ret.pointC.X = Count > 6 ? ValueF[6] : 0.0f; 635 ret.pointC.Y = Count > 7 ? ValueF[7] : 0.0f; 636 ret.pointC.Z = Count > 8 ? ValueF[8] : 0.0f; 637 } 638 else 639 { 640 ret.pointA.X = Count > 0 ? (f32)ValueI[0] : 0.0f; 641 ret.pointA.Y = Count > 1 ? (f32)ValueI[1] : 0.0f; 642 ret.pointA.Z = Count > 2 ? (f32)ValueI[2] : 0.0f; 643 ret.pointB.X = Count > 3 ? (f32)ValueI[3] : 0.0f; 644 ret.pointB.Y = Count > 4 ? (f32)ValueI[4] : 0.0f; 645 ret.pointB.Z = Count > 5 ? (f32)ValueI[5] : 0.0f; 646 ret.pointC.X = Count > 6 ? (f32)ValueI[6] : 0.0f; 647 ret.pointC.Y = Count > 7 ? (f32)ValueI[7] : 0.0f; 648 ret.pointC.Z = Count > 8 ? (f32)ValueI[8] : 0.0f; 649 } 650 651 return ret; 652 } 653 getPlane()654 virtual core::plane3df getPlane() 655 { 656 core::plane3df ret; 657 658 if (IsFloat) 659 { 660 ret.Normal.X = Count > 0 ? ValueF[0] : 0.0f; 661 ret.Normal.Y = Count > 1 ? ValueF[1] : 0.0f; 662 ret.Normal.Z = Count > 2 ? ValueF[2] : 0.0f; 663 ret.D = Count > 3 ? ValueF[3] : 0.0f; 664 } 665 else 666 { 667 ret.Normal.X = Count > 0 ? (f32)ValueI[0] : 0.0f; 668 ret.Normal.Y = Count > 1 ? (f32)ValueI[1] : 0.0f; 669 ret.Normal.Z = Count > 2 ? (f32)ValueI[2] : 0.0f; 670 ret.D = Count > 3 ? (f32)ValueI[3] : 0.0f; 671 } 672 673 return ret; 674 } 675 getBBox()676 virtual core::aabbox3df getBBox() 677 { 678 core::aabbox3df ret; 679 if (IsFloat) 680 { 681 ret.MinEdge.X = Count > 0 ? ValueF[0] : 0.0f; 682 ret.MinEdge.Y = Count > 1 ? ValueF[1] : 0.0f; 683 ret.MinEdge.Z = Count > 2 ? ValueF[2] : 0.0f; 684 ret.MaxEdge.X = Count > 3 ? ValueF[3] : 0.0f; 685 ret.MaxEdge.Y = Count > 4 ? ValueF[4] : 0.0f; 686 ret.MaxEdge.Z = Count > 5 ? ValueF[5] : 0.0f; 687 } 688 else 689 { 690 ret.MinEdge.X = Count > 0 ? (f32)ValueI[0] : 0.0f; 691 ret.MinEdge.Y = Count > 1 ? (f32)ValueI[1] : 0.0f; 692 ret.MinEdge.Z = Count > 2 ? (f32)ValueI[2] : 0.0f; 693 ret.MaxEdge.X = Count > 3 ? (f32)ValueI[3] : 0.0f; 694 ret.MaxEdge.Y = Count > 4 ? (f32)ValueI[4] : 0.0f; 695 ret.MaxEdge.Z = Count > 5 ? (f32)ValueI[5] : 0.0f; 696 } 697 return ret; 698 699 } 700 getLine2d()701 virtual core::line2df getLine2d() 702 { 703 core::line2df ret; 704 if (IsFloat) 705 { 706 ret.start.X = Count > 0 ? ValueF[0] : 0.0f; 707 ret.start.Y = Count > 1 ? ValueF[1] : 0.0f; 708 ret.end.X = Count > 2 ? ValueF[2] : 0.0f; 709 ret.end.Y = Count > 3 ? ValueF[3] : 0.0f; 710 } 711 else 712 { 713 ret.start.X = Count > 0 ? (f32)ValueI[0] : 0.0f; 714 ret.start.Y = Count > 1 ? (f32)ValueI[1] : 0.0f; 715 ret.end.X = Count > 2 ? (f32)ValueI[2] : 0.0f; 716 ret.end.Y = Count > 3 ? (f32)ValueI[3] : 0.0f; 717 } 718 return ret; 719 } 720 getLine3d()721 virtual core::line3df getLine3d() 722 { 723 core::line3df ret; 724 if (IsFloat) 725 { 726 ret.start.X = Count > 0 ? ValueF[0] : 0.0f; 727 ret.start.Y = Count > 1 ? ValueF[1] : 0.0f; 728 ret.start.Z = Count > 2 ? ValueF[2] : 0.0f; 729 ret.end.X = Count > 3 ? ValueF[3] : 0.0f; 730 ret.end.Y = Count > 4 ? ValueF[4] : 0.0f; 731 ret.end.Z = Count > 5 ? ValueF[5] : 0.0f; 732 } 733 else 734 { 735 ret.start.X = Count > 0 ? (f32)ValueI[0] : 0.0f; 736 ret.start.Y = Count > 1 ? (f32)ValueI[1] : 0.0f; 737 ret.start.Z = Count > 2 ? (f32)ValueI[2] : 0.0f; 738 ret.end.X = Count > 3 ? (f32)ValueI[3] : 0.0f; 739 ret.end.Y = Count > 4 ? (f32)ValueI[4] : 0.0f; 740 ret.end.Z = Count > 5 ? (f32)ValueI[5] : 0.0f; 741 } 742 return ret; 743 } 744 745 //! get float array getFloatArray()746 virtual core::array<f32> getFloatArray() 747 { 748 if (!IsFloat) 749 { 750 ValueF.clear(); 751 for (u32 i=0; i<Count; ++i) 752 ValueF.push_back( (f32) ValueI[i] ); 753 } 754 return ValueF; 755 } 756 757 //! get int array getIntArray()758 virtual core::array<s32> getIntArray() 759 { 760 if (IsFloat) 761 { 762 ValueI.clear(); 763 for (u32 i=0; i<Count; ++i) 764 ValueI.push_back( (s32) ValueF[i] ); 765 } 766 return ValueI; 767 } 768 769 770 // setting values setInt(s32 intValue)771 virtual void setInt(s32 intValue) 772 { 773 // set all values 774 for (u32 i=0; i < Count; ++i) 775 if (IsFloat) 776 ValueF[i] = (f32)intValue; 777 else 778 ValueI[i] = intValue; 779 } 780 setFloat(f32 floatValue)781 virtual void setFloat(f32 floatValue) 782 { 783 // set all values 784 for (u32 i=0; i < Count; ++i) 785 if (IsFloat) 786 ValueF[i] = floatValue; 787 else 788 ValueI[i] = (s32)floatValue; 789 } 790 setBool(bool boolValue)791 virtual void setBool(bool boolValue) 792 { 793 setInt( boolValue ? 1 : 0); 794 } 795 setString(const char * text)796 virtual void setString(const char* text) 797 { 798 // parse text 799 800 const char* P = (const char*)text; 801 802 reset(); 803 804 u32 i=0; 805 806 for ( i=0; i<Count && *P; ++i ) 807 { 808 while(*P && P[0]!='-' && ( P[0]==' ' || (P[0] < '0' || P[0] > '9') ) ) 809 ++P; 810 811 // set value 812 if ( *P) 813 { 814 if (IsFloat) 815 { 816 f32 c = 0; 817 P = core::fast_atof_move(P, c); 818 ValueF[i] = c; 819 } 820 else 821 { 822 // todo: fix this to read ints properly 823 f32 c = 0; 824 P = core::fast_atof_move(P, c); 825 ValueI[i] = (s32)c; 826 827 } 828 } 829 } 830 // todo: warning message 831 //if (i < Count-1) 832 //{ 833 // 834 //} 835 } 836 setPosition(core::position2di v)837 virtual void setPosition(core::position2di v) 838 { 839 reset(); 840 if (IsFloat) 841 { 842 if (Count > 0) ValueF[0] = (f32)v.X; 843 if (Count > 1) ValueF[1] = (f32)v.Y; 844 } 845 else 846 { 847 if (Count > 0) ValueI[0] = v.X; 848 if (Count > 1) ValueI[1] = v.Y; 849 } 850 } 851 setVector(core::vector3df v)852 virtual void setVector(core::vector3df v) 853 { 854 reset(); 855 if (IsFloat) 856 { 857 if (Count > 0) ValueF[0] = v.X; 858 if (Count > 1) ValueF[1] = v.Y; 859 if (Count > 2) ValueF[2] = v.Z; 860 } 861 else 862 { 863 if (Count > 0) ValueI[0] = (s32)v.X; 864 if (Count > 1) ValueI[1] = (s32)v.Y; 865 if (Count > 2) ValueI[2] = (s32)v.Z; 866 } 867 } 868 setColor(video::SColorf color)869 virtual void setColor(video::SColorf color) 870 { 871 reset(); 872 if (IsFloat) 873 { 874 if (Count > 0) ValueF[0] = color.r; 875 if (Count > 1) ValueF[1] = color.g; 876 if (Count > 2) ValueF[2] = color.b; 877 if (Count > 3) ValueF[3] = color.a; 878 } 879 else 880 { 881 if (Count > 0) ValueI[0] = (s32)(color.r * 255); 882 if (Count > 1) ValueI[1] = (s32)(color.g * 255); 883 if (Count > 2) ValueI[2] = (s32)(color.b * 255); 884 if (Count > 3) ValueI[3] = (s32)(color.a * 255); 885 } 886 887 } 888 setColor(video::SColor color)889 virtual void setColor(video::SColor color) 890 { 891 reset(); 892 if (IsFloat) 893 { 894 if (Count > 0) ValueF[0] = (f32)color.getRed() / 255.0f; 895 if (Count > 1) ValueF[1] = (f32)color.getGreen() / 255.0f; 896 if (Count > 2) ValueF[2] = (f32)color.getBlue() / 255.0f; 897 if (Count > 3) ValueF[3] = (f32)color.getAlpha() / 255.0f; 898 } 899 else 900 { 901 if (Count > 0) ValueI[0] = color.getRed(); 902 if (Count > 1) ValueI[1] = color.getGreen(); 903 if (Count > 2) ValueI[2] = color.getBlue(); 904 if (Count > 3) ValueI[3] = color.getAlpha(); 905 } 906 } 907 setRect(core::rect<s32> value)908 virtual void setRect(core::rect<s32> value) 909 { 910 reset(); 911 if (IsFloat) 912 { 913 if (Count > 0) ValueF[0] = (f32)value.UpperLeftCorner.X; 914 if (Count > 1) ValueF[1] = (f32)value.UpperLeftCorner.Y; 915 if (Count > 2) ValueF[2] = (f32)value.LowerRightCorner.X; 916 if (Count > 3) ValueF[3] = (f32)value.LowerRightCorner.Y; 917 } 918 else 919 { 920 if (Count > 0) ValueI[0] = value.UpperLeftCorner.X; 921 if (Count > 1) ValueI[1] = value.UpperLeftCorner.Y; 922 if (Count > 2) ValueI[2] = value.LowerRightCorner.X; 923 if (Count > 3) ValueI[3] = value.LowerRightCorner.Y; 924 } 925 } 926 setMatrix(core::matrix4 value)927 virtual void setMatrix(core::matrix4 value) 928 { 929 reset(); 930 if (IsFloat) 931 { 932 for (u32 r=0; r<4; ++r) 933 for (u32 c=0; c<4; ++c) 934 if (Count > c+r*4) 935 ValueF[c+r*4] = value(r,c); 936 } 937 else 938 { 939 for (u32 r=0; r<4; ++r) 940 for (u32 c=0; c<4; ++c) 941 if (Count > c+r*4) 942 ValueI[c+r*4] = (s32)value(r,c); 943 } 944 } 945 setQuaternion(core::quaternion value)946 virtual void setQuaternion(core::quaternion value) 947 { 948 reset(); 949 if (IsFloat) 950 { 951 if (Count > 0) ValueF[0] = value.X; 952 if (Count > 1) ValueF[1] = value.Y; 953 if (Count > 2) ValueF[2] = value.Z; 954 if (Count > 3) ValueF[3] = value.W; 955 } 956 else 957 { 958 if (Count > 0) ValueI[0] = (s32)value.X; 959 if (Count > 1) ValueI[1] = (s32)value.Y; 960 if (Count > 2) ValueI[2] = (s32)value.Z; 961 if (Count > 3) ValueI[3] = (s32)value.W; 962 } 963 } 964 setBoundingBox(core::aabbox3d<f32> value)965 virtual void setBoundingBox(core::aabbox3d<f32> value) 966 { 967 reset(); 968 if (IsFloat) 969 { 970 if (Count > 0) ValueF[0] = value.MinEdge.X; 971 if (Count > 1) ValueF[1] = value.MinEdge.Y; 972 if (Count > 2) ValueF[2] = value.MinEdge.Z; 973 if (Count > 3) ValueF[3] = value.MaxEdge.X; 974 if (Count > 4) ValueF[4] = value.MaxEdge.Y; 975 if (Count > 5) ValueF[5] = value.MaxEdge.Z; 976 } 977 else 978 { 979 if (Count > 0) ValueI[0] = (s32)value.MinEdge.X; 980 if (Count > 1) ValueI[1] = (s32)value.MinEdge.Y; 981 if (Count > 2) ValueI[2] = (s32)value.MinEdge.Z; 982 if (Count > 3) ValueI[3] = (s32)value.MaxEdge.X; 983 if (Count > 4) ValueI[4] = (s32)value.MaxEdge.Y; 984 if (Count > 5) ValueI[5] = (s32)value.MaxEdge.Z; 985 } 986 } 987 setPlane(core::plane3df value)988 virtual void setPlane(core::plane3df value) 989 { 990 reset(); 991 if (IsFloat) 992 { 993 if (Count > 0) ValueF[0] = value.Normal.X; 994 if (Count > 1) ValueF[1] = value.Normal.Y; 995 if (Count > 2) ValueF[2] = value.Normal.Z; 996 if (Count > 3) ValueF[3] = value.D; 997 } 998 else 999 { 1000 if (Count > 0) ValueI[0] = (s32)value.Normal.X; 1001 if (Count > 1) ValueI[1] = (s32)value.Normal.Y; 1002 if (Count > 2) ValueI[2] = (s32)value.Normal.Z; 1003 if (Count > 3) ValueI[3] = (s32)value.D; 1004 } 1005 } 1006 setTriangle3d(core::triangle3df value)1007 virtual void setTriangle3d(core::triangle3df value) 1008 { 1009 reset(); 1010 if (IsFloat) 1011 { 1012 if (Count > 0) ValueF[0] = value.pointA.X; 1013 if (Count > 1) ValueF[1] = value.pointA.Y; 1014 if (Count > 2) ValueF[2] = value.pointA.Z; 1015 if (Count > 3) ValueF[3] = value.pointB.X; 1016 if (Count > 4) ValueF[4] = value.pointB.Y; 1017 if (Count > 5) ValueF[5] = value.pointB.Z; 1018 if (Count > 6) ValueF[6] = value.pointC.X; 1019 if (Count > 7) ValueF[7] = value.pointC.Y; 1020 if (Count > 8) ValueF[8] = value.pointC.Z; 1021 } 1022 else 1023 { 1024 if (Count > 0) ValueI[0] = (s32)value.pointA.X; 1025 if (Count > 1) ValueI[1] = (s32)value.pointA.Y; 1026 if (Count > 2) ValueI[2] = (s32)value.pointA.Z; 1027 if (Count > 3) ValueI[3] = (s32)value.pointB.X; 1028 if (Count > 4) ValueI[4] = (s32)value.pointB.Y; 1029 if (Count > 5) ValueI[5] = (s32)value.pointB.Z; 1030 if (Count > 6) ValueI[6] = (s32)value.pointC.X; 1031 if (Count > 7) ValueI[7] = (s32)value.pointC.Y; 1032 if (Count > 8) ValueI[8] = (s32)value.pointC.Z; 1033 } 1034 } 1035 setVector2d(core::vector2df v)1036 virtual void setVector2d(core::vector2df v) 1037 { 1038 reset(); 1039 if (IsFloat) 1040 { 1041 if (Count > 0) ValueF[0] = v.X; 1042 if (Count > 1) ValueF[1] = v.Y; 1043 } 1044 else 1045 { 1046 if (Count > 0) ValueI[0] = (s32)v.X; 1047 if (Count > 1) ValueI[1] = (s32)v.Y; 1048 } 1049 } 1050 setVector2d(core::vector2di v)1051 virtual void setVector2d(core::vector2di v) 1052 { 1053 reset(); 1054 if (IsFloat) 1055 { 1056 if (Count > 0) ValueF[0] = (f32)v.X; 1057 if (Count > 1) ValueF[1] = (f32)v.Y; 1058 } 1059 else 1060 { 1061 if (Count > 0) ValueI[0] = v.X; 1062 if (Count > 1) ValueI[1] = v.Y; 1063 } 1064 } 1065 setLine2d(core::line2di v)1066 virtual void setLine2d(core::line2di v) 1067 { 1068 reset(); 1069 if (IsFloat) 1070 { 1071 if (Count > 0) ValueF[0] = (f32)v.start.X; 1072 if (Count > 1) ValueF[1] = (f32)v.start.Y; 1073 if (Count > 2) ValueF[2] = (f32)v.end.X; 1074 if (Count > 3) ValueF[3] = (f32)v.end.Y; 1075 } 1076 else 1077 { 1078 if (Count > 0) ValueI[0] = v.start.X; 1079 if (Count > 1) ValueI[1] = v.start.Y; 1080 if (Count > 2) ValueI[2] = v.end.X; 1081 if (Count > 3) ValueI[3] = v.end.Y; 1082 } 1083 } 1084 setLine2d(core::line2df v)1085 virtual void setLine2d(core::line2df v) 1086 { 1087 reset(); 1088 if (IsFloat) 1089 { 1090 if (Count > 0) ValueF[0] = v.start.X; 1091 if (Count > 1) ValueF[1] = v.start.Y; 1092 if (Count > 2) ValueF[2] = v.end.X; 1093 if (Count > 3) ValueF[3] = v.end.Y; 1094 } 1095 else 1096 { 1097 if (Count > 0) ValueI[0] = (s32)v.start.X; 1098 if (Count > 1) ValueI[1] = (s32)v.start.Y; 1099 if (Count > 2) ValueI[2] = (s32)v.end.X; 1100 if (Count > 3) ValueI[3] = (s32)v.end.Y; 1101 } 1102 } 1103 setDimension2d(core::dimension2du v)1104 virtual void setDimension2d(core::dimension2du v) 1105 { 1106 reset(); 1107 if (IsFloat) 1108 { 1109 if (Count > 0) ValueF[0] = (f32)v.Width; 1110 if (Count > 1) ValueF[1] = (f32)v.Height; 1111 } 1112 else 1113 { 1114 if (Count > 0) ValueI[0] = (s32)v.Width; 1115 if (Count > 1) ValueI[1] = (s32)v.Height; 1116 } 1117 } 1118 1119 //! set float array setFloatArray(core::array<f32> & vals)1120 virtual void setFloatArray(core::array<f32> &vals) 1121 { 1122 reset(); 1123 1124 for (u32 i=0; i<vals.size() && i<Count; ++i) 1125 { 1126 if (IsFloat) 1127 ValueF[i] = vals[i]; 1128 else 1129 ValueI[i] = (s32)vals[i]; 1130 } 1131 } 1132 1133 //! set int array setIntArray(core::array<s32> & vals)1134 virtual void setIntArray(core::array<s32> &vals) 1135 { 1136 reset(); 1137 1138 for (u32 i=0; i<vals.size() && i<Count; ++i) 1139 { 1140 if (IsFloat) 1141 ValueF[i] = (f32)vals[i]; 1142 else 1143 ValueI[i] = vals[i]; 1144 } 1145 } 1146 1147 1148 //! is it a number list? isNumberList()1149 virtual bool isNumberList() 1150 { 1151 return true; 1152 } 1153 1154 //! is it a float list? isFloat()1155 virtual bool isFloat() 1156 { 1157 return IsFloat; 1158 } 1159 getType()1160 virtual E_ATTRIBUTE_TYPE getType() const 1161 { 1162 if (IsFloat) 1163 return EAT_FLOATARRAY; 1164 else 1165 return EAT_INTARRAY; 1166 } 1167 getTypeString()1168 virtual const wchar_t* getTypeString() const 1169 { 1170 if (IsFloat) 1171 return L"floatlist"; 1172 else 1173 return L"intlist"; 1174 } 1175 1176 protected: 1177 1178 //! clear all values reset()1179 void reset() 1180 { 1181 if (IsFloat) 1182 for (u32 i=0; i < Count ; ++i) 1183 ValueF[i] = 0.0f; 1184 else 1185 for (u32 i=0; i < Count ; ++i) 1186 ValueI[i] = 0; 1187 } 1188 1189 core::array<s32> ValueI; 1190 core::array<f32> ValueF; 1191 u32 Count; 1192 bool IsFloat; 1193 }; 1194 1195 1196 // Attribute implemented for floating point colors 1197 class CColorfAttribute : public CNumbersAttribute 1198 { 1199 public: 1200 CColorfAttribute(const char * name,video::SColorf value)1201 CColorfAttribute(const char* name, video::SColorf value) : CNumbersAttribute(name, value) {} 1202 getInt()1203 virtual s32 getInt() 1204 { 1205 return getColor().color; 1206 } 1207 getFloat()1208 virtual f32 getFloat() 1209 { 1210 return (f32)getColor().color; 1211 } 1212 setInt(s32 intValue)1213 virtual void setInt(s32 intValue) 1214 { 1215 video::SColorf c = video::SColor(intValue); 1216 ValueF[0] = c.r; 1217 ValueF[1] = c.g; 1218 ValueF[2] = c.b; 1219 ValueF[3] = c.a; 1220 } 1221 setFloat(f32 floatValue)1222 virtual void setFloat(f32 floatValue) 1223 { 1224 setInt((s32)floatValue); 1225 } 1226 getType()1227 virtual E_ATTRIBUTE_TYPE getType() const 1228 { 1229 return EAT_COLORF; 1230 } 1231 getTypeString()1232 virtual const wchar_t* getTypeString() const 1233 { 1234 return L"colorf"; 1235 } 1236 }; 1237 1238 1239 1240 // Attribute implemented for colors 1241 class CColorAttribute : public CNumbersAttribute 1242 { 1243 public: 1244 CColorAttribute(const char * name,const video::SColorf & value)1245 CColorAttribute(const char* name, const video::SColorf& value) : CNumbersAttribute(name, value) {} 1246 CColorAttribute(const char * name,const video::SColor & value)1247 CColorAttribute(const char* name, const video::SColor& value) : CNumbersAttribute(name, value) {} 1248 getInt()1249 virtual s32 getInt() 1250 { 1251 return getColor().color; 1252 } 1253 getFloat()1254 virtual f32 getFloat() 1255 { 1256 return (f32)getColor().color; 1257 } 1258 setInt(s32 intValue)1259 virtual void setInt(s32 intValue) 1260 { 1261 video::SColorf c = video::SColor(intValue); 1262 ValueF[0] = c.r; 1263 ValueF[1] = c.g; 1264 ValueF[2] = c.b; 1265 ValueF[3] = c.a; 1266 } 1267 setFloat(f32 floatValue)1268 virtual void setFloat(f32 floatValue) 1269 { 1270 setInt((s32)floatValue); 1271 } 1272 getStringW()1273 virtual core::stringw getStringW() 1274 { 1275 char tmp[10]; 1276 const video::SColor c = getColor(); 1277 sprintf(tmp, "%02x%02x%02x%02x", c.getAlpha(), c.getRed(), c.getGreen(), c.getBlue()); 1278 return core::stringw(tmp); 1279 } 1280 setString(const char * text)1281 virtual void setString(const char* text) 1282 { 1283 u32 c; 1284 if (sscanf(text, "%08x", &c)!=1) 1285 { 1286 CNumbersAttribute::setString(text); 1287 } 1288 else 1289 setColor(c); 1290 } 1291 getType()1292 virtual E_ATTRIBUTE_TYPE getType() const 1293 { 1294 return EAT_COLOR; 1295 } 1296 1297 getTypeString()1298 virtual const wchar_t* getTypeString() const 1299 { 1300 return L"color"; 1301 } 1302 1303 }; 1304 1305 1306 // Attribute implemented for 3d vectors 1307 class CVector3DAttribute : public CNumbersAttribute 1308 { 1309 public: 1310 CVector3DAttribute(const char * name,core::vector3df value)1311 CVector3DAttribute(const char* name, core::vector3df value) : CNumbersAttribute(name, value) {} 1312 getType()1313 virtual E_ATTRIBUTE_TYPE getType() const 1314 { 1315 return EAT_VECTOR3D; 1316 } 1317 getMatrix()1318 virtual core::matrix4 getMatrix() 1319 { 1320 core::matrix4 ret; 1321 ret.makeIdentity(); 1322 ret.setTranslation( core::vector3df(ValueF[0],ValueF[1],ValueF[2]) ); 1323 return ret; 1324 } 1325 getTypeString()1326 virtual const wchar_t* getTypeString() const 1327 { 1328 return L"vector3d"; 1329 } 1330 }; 1331 1332 // Attribute implemented for 2d vectors 1333 class CVector2DAttribute : public CNumbersAttribute 1334 { 1335 public: 1336 CVector2DAttribute(const char * name,core::vector2df value)1337 CVector2DAttribute(const char* name, core::vector2df value) : CNumbersAttribute(name, value) {} 1338 getType()1339 virtual E_ATTRIBUTE_TYPE getType() const 1340 { 1341 return EAT_VECTOR2D; 1342 } 1343 getTypeString()1344 virtual const wchar_t* getTypeString() const 1345 { 1346 return L"vector2d"; 1347 } 1348 }; 1349 1350 // Attribute implemented for 2d vectors 1351 class CPosition2DAttribute : public CNumbersAttribute 1352 { 1353 public: 1354 CPosition2DAttribute(const char * name,core::position2di value)1355 CPosition2DAttribute(const char* name, core::position2di value) : CNumbersAttribute(name, value) {} 1356 getType()1357 virtual E_ATTRIBUTE_TYPE getType() const 1358 { 1359 return EAT_POSITION2D; 1360 } 1361 getTypeString()1362 virtual const wchar_t* getTypeString() const 1363 { 1364 return L"position"; 1365 } 1366 }; 1367 1368 1369 1370 // Attribute implemented for rectangles 1371 class CRectAttribute : public CNumbersAttribute 1372 { 1373 public: 1374 CRectAttribute(const char * name,core::rect<s32> value)1375 CRectAttribute(const char* name, core::rect<s32> value) : CNumbersAttribute(name, value) { } 1376 getType()1377 virtual E_ATTRIBUTE_TYPE getType() const 1378 { 1379 return EAT_RECT; 1380 } 1381 getTypeString()1382 virtual const wchar_t* getTypeString() const 1383 { 1384 return L"rect"; 1385 } 1386 }; 1387 1388 1389 // Attribute implemented for dimension 1390 class CDimension2dAttribute : public CNumbersAttribute 1391 { 1392 public: 1393 CDimension2dAttribute(const char * name,core::dimension2d<u32> value)1394 CDimension2dAttribute (const char* name, core::dimension2d<u32> value) : CNumbersAttribute(name, value) { } 1395 getType()1396 virtual E_ATTRIBUTE_TYPE getType() const 1397 { 1398 return EAT_DIMENSION2D; 1399 } 1400 getTypeString()1401 virtual const wchar_t* getTypeString() const 1402 { 1403 return L"dimension2d"; 1404 } 1405 }; 1406 1407 // Attribute implemented for matrices 1408 class CMatrixAttribute : public CNumbersAttribute 1409 { 1410 public: 1411 CMatrixAttribute(const char * name,core::matrix4 value)1412 CMatrixAttribute(const char* name, core::matrix4 value) : CNumbersAttribute(name, value) { } 1413 getType()1414 virtual E_ATTRIBUTE_TYPE getType() const 1415 { 1416 return EAT_MATRIX; 1417 } 1418 getQuaternion()1419 virtual core::quaternion getQuaternion() 1420 { 1421 return core::quaternion(getMatrix()); 1422 } 1423 getTypeString()1424 virtual const wchar_t* getTypeString() const 1425 { 1426 return L"matrix"; 1427 } 1428 }; 1429 1430 // Attribute implemented for quaternions 1431 class CQuaternionAttribute : public CNumbersAttribute 1432 { 1433 public: 1434 CQuaternionAttribute(const char * name,core::quaternion value)1435 CQuaternionAttribute(const char* name, core::quaternion value) : CNumbersAttribute(name, value) { } 1436 getType()1437 virtual E_ATTRIBUTE_TYPE getType() const 1438 { 1439 return EAT_QUATERNION; 1440 } 1441 getMatrix()1442 virtual core::matrix4 getMatrix() 1443 { 1444 return getQuaternion().getMatrix(); 1445 } 1446 getTypeString()1447 virtual const wchar_t* getTypeString() const 1448 { 1449 return L"quaternion"; 1450 } 1451 }; 1452 1453 1454 // Attribute implemented for bounding boxes 1455 class CBBoxAttribute : public CNumbersAttribute 1456 { 1457 public: 1458 CBBoxAttribute(const char * name,core::aabbox3df value)1459 CBBoxAttribute(const char* name, core::aabbox3df value) : CNumbersAttribute(name, value) { } 1460 getType()1461 virtual E_ATTRIBUTE_TYPE getType() const 1462 { 1463 return EAT_BBOX; 1464 } 1465 getTypeString()1466 virtual const wchar_t* getTypeString() const 1467 { 1468 return L"box3d"; 1469 } 1470 }; 1471 1472 // Attribute implemented for planes 1473 class CPlaneAttribute : public CNumbersAttribute 1474 { 1475 public: 1476 CPlaneAttribute(const char * name,core::plane3df value)1477 CPlaneAttribute(const char* name, core::plane3df value) : CNumbersAttribute(name, value) { } 1478 getType()1479 virtual E_ATTRIBUTE_TYPE getType() const 1480 { 1481 return EAT_PLANE; 1482 } 1483 getTypeString()1484 virtual const wchar_t* getTypeString() const 1485 { 1486 return L"plane"; 1487 } 1488 }; 1489 1490 // Attribute implemented for triangles 1491 class CTriangleAttribute : public CNumbersAttribute 1492 { 1493 public: 1494 CTriangleAttribute(const char * name,core::triangle3df value)1495 CTriangleAttribute(const char* name, core::triangle3df value) : CNumbersAttribute(name, value) { } 1496 getType()1497 virtual E_ATTRIBUTE_TYPE getType() const 1498 { 1499 return EAT_TRIANGLE3D; 1500 } 1501 getPlane()1502 virtual core::plane3df getPlane() 1503 { 1504 return getTriangle().getPlane(); 1505 } 1506 getTypeString()1507 virtual const wchar_t* getTypeString() const 1508 { 1509 return L"triangle"; 1510 } 1511 }; 1512 1513 1514 // Attribute implemented for 2d lines 1515 class CLine2dAttribute : public CNumbersAttribute 1516 { 1517 public: 1518 CLine2dAttribute(const char * name,core::line2df value)1519 CLine2dAttribute(const char* name, core::line2df value) : CNumbersAttribute(name, value) { } 1520 getType()1521 virtual E_ATTRIBUTE_TYPE getType() const 1522 { 1523 return EAT_LINE2D; 1524 } 1525 getTypeString()1526 virtual const wchar_t* getTypeString() const 1527 { 1528 return L"line2d"; 1529 } 1530 }; 1531 1532 // Attribute implemented for 3d lines 1533 class CLine3dAttribute : public CNumbersAttribute 1534 { 1535 public: 1536 CLine3dAttribute(const char * name,core::line3df value)1537 CLine3dAttribute(const char* name, core::line3df value) : CNumbersAttribute(name, value) { } 1538 getType()1539 virtual E_ATTRIBUTE_TYPE getType() const 1540 { 1541 return EAT_LINE3D; 1542 } 1543 getTypeString()1544 virtual const wchar_t* getTypeString() const 1545 { 1546 return L"line3d"; 1547 } 1548 }; 1549 1550 1551 // vector2df 1552 // dimension2du 1553 1554 /* 1555 Special attributes 1556 */ 1557 1558 // Attribute implemented for enumeration literals 1559 class CEnumAttribute : public IAttribute 1560 { 1561 public: 1562 CEnumAttribute(const char * name,const char * value,const char * const * literals)1563 CEnumAttribute(const char* name, const char* value, const char* const* literals) 1564 { 1565 Name = name; 1566 setEnum(value, literals); 1567 } 1568 setEnum(const char * enumValue,const char * const * enumerationLiterals)1569 virtual void setEnum(const char* enumValue, const char* const* enumerationLiterals) 1570 { 1571 int literalCount = 0; 1572 1573 if (enumerationLiterals) 1574 { 1575 s32 i; 1576 for (i=0; enumerationLiterals[i]; ++i) 1577 ++literalCount; 1578 1579 EnumLiterals.reallocate(literalCount); 1580 for (i=0; enumerationLiterals[i]; ++i) 1581 EnumLiterals.push_back(enumerationLiterals[i]); 1582 } 1583 1584 setString(enumValue); 1585 } 1586 getInt()1587 virtual s32 getInt() 1588 { 1589 for (u32 i=0; i < EnumLiterals.size(); ++i) 1590 if (Value.equals_ignore_case(EnumLiterals[i])) 1591 { 1592 return (s32)i; 1593 } 1594 1595 return -1; 1596 } 1597 getFloat()1598 virtual f32 getFloat() 1599 { 1600 return (f32)getInt(); 1601 } 1602 getBool()1603 virtual bool getBool() 1604 { 1605 return (getInt() != 0); // does not make a lot of sense, I know 1606 } 1607 getString()1608 virtual core::stringc getString() 1609 { 1610 return Value; 1611 } 1612 getStringW()1613 virtual core::stringw getStringW() 1614 { 1615 return core::stringw(Value.c_str()); 1616 } 1617 setInt(s32 intValue)1618 virtual void setInt(s32 intValue) 1619 { 1620 if (intValue>=0 && intValue<(s32)EnumLiterals.size()) 1621 Value = EnumLiterals[intValue]; 1622 else 1623 Value = ""; 1624 } 1625 setFloat(f32 floatValue)1626 virtual void setFloat(f32 floatValue) 1627 { 1628 setInt((s32)floatValue); 1629 }; 1630 setString(const char * text)1631 virtual void setString(const char* text) 1632 { 1633 Value = text; 1634 } 1635 getEnum()1636 virtual const char* getEnum() 1637 { 1638 return Value.c_str(); 1639 } 1640 getType()1641 virtual E_ATTRIBUTE_TYPE getType() const 1642 { 1643 return EAT_ENUM; 1644 } 1645 1646 getTypeString()1647 virtual const wchar_t* getTypeString() const 1648 { 1649 return L"enum"; 1650 } 1651 1652 core::stringc Value; 1653 core::array<core::stringc> EnumLiterals; 1654 }; 1655 1656 1657 1658 1659 1660 // Attribute implemented for strings 1661 class CStringAttribute : public IAttribute 1662 { 1663 public: 1664 CStringAttribute(const char * name,const char * value)1665 CStringAttribute(const char* name, const char* value) 1666 { 1667 IsStringW=false; 1668 Name = name; 1669 setString(value); 1670 } 1671 CStringAttribute(const char * name,const wchar_t * value)1672 CStringAttribute(const char* name, const wchar_t* value) 1673 { 1674 IsStringW = true; 1675 Name = name; 1676 setString(value); 1677 } 1678 CStringAttribute(const char * name,void * binaryData,s32 lenghtInBytes)1679 CStringAttribute(const char* name, void* binaryData, s32 lenghtInBytes) 1680 { 1681 IsStringW=false; 1682 Name = name; 1683 setBinary(binaryData, lenghtInBytes); 1684 } 1685 getInt()1686 virtual s32 getInt() 1687 { 1688 if (IsStringW) 1689 return atoi(core::stringc(ValueW.c_str()).c_str()); 1690 else 1691 return atoi(Value.c_str()); 1692 } 1693 getFloat()1694 virtual f32 getFloat() 1695 { 1696 if (IsStringW) 1697 return core::fast_atof(core::stringc(ValueW.c_str()).c_str()); 1698 else 1699 return core::fast_atof(Value.c_str()); 1700 } 1701 getBool()1702 virtual bool getBool() 1703 { 1704 if (IsStringW) 1705 return ValueW.equals_ignore_case(L"true"); 1706 else 1707 return Value.equals_ignore_case("true"); 1708 } 1709 getString()1710 virtual core::stringc getString() 1711 { 1712 if (IsStringW) 1713 return core::stringc(ValueW.c_str()); 1714 else 1715 return Value; 1716 } getStringW()1717 virtual core::stringw getStringW() 1718 { 1719 if (IsStringW) 1720 return ValueW; 1721 else 1722 return core::stringw(Value.c_str()); 1723 } 1724 setInt(s32 intValue)1725 virtual void setInt(s32 intValue) 1726 { 1727 if (IsStringW) 1728 ValueW = core::stringw(intValue); 1729 else 1730 Value = core::stringc(intValue); 1731 } 1732 setFloat(f32 floatValue)1733 virtual void setFloat(f32 floatValue) 1734 { 1735 if (IsStringW) 1736 { 1737 ValueW = core::stringw((double)floatValue); 1738 } 1739 else 1740 { 1741 Value = core::stringc((double)floatValue); 1742 } 1743 }; 1744 setString(const char * text)1745 virtual void setString(const char* text) 1746 { 1747 if (IsStringW) 1748 ValueW = core::stringw(text); 1749 else 1750 Value = text; 1751 } 1752 setString(const wchar_t * text)1753 virtual void setString(const wchar_t* text) 1754 { 1755 if (IsStringW) 1756 ValueW = text; 1757 else 1758 Value = core::stringc(text); 1759 } 1760 getType()1761 virtual E_ATTRIBUTE_TYPE getType() const 1762 { 1763 return EAT_STRING; 1764 } 1765 1766 getTypeString()1767 virtual const wchar_t* getTypeString() const 1768 { 1769 return L"string"; 1770 } 1771 getBinary(void * outdata,s32 maxLength)1772 virtual void getBinary(void* outdata, s32 maxLength) 1773 { 1774 s32 dataSize = maxLength; 1775 c8* datac8 = (c8*)(outdata); 1776 s32 p = 0; 1777 const c8* dataString = Value.c_str(); 1778 1779 for (s32 i=0; i<dataSize; ++i) 1780 datac8[i] = 0; 1781 1782 while(dataString[p] && p<dataSize) 1783 { 1784 s32 v = getByteFromHex((c8)dataString[p*2]) * 16; 1785 1786 if (dataString[(p*2)+1]) 1787 v += getByteFromHex((c8)dataString[(p*2)+1]); 1788 1789 datac8[p] = v; 1790 ++p; 1791 } 1792 }; 1793 setBinary(void * data,s32 maxLength)1794 virtual void setBinary(void* data, s32 maxLength) 1795 { 1796 s32 dataSize = maxLength; 1797 c8* datac8 = (c8*)(data); 1798 char tmp[3]; 1799 tmp[2] = 0; 1800 Value = ""; 1801 1802 for (s32 b=0; b<dataSize; ++b) 1803 { 1804 getHexStrFromByte(datac8[b], tmp); 1805 Value.append(tmp); 1806 } 1807 }; 1808 1809 bool IsStringW; 1810 core::stringc Value; 1811 core::stringw ValueW; 1812 1813 protected: 1814 getByteFromHex(c8 h)1815 static inline s32 getByteFromHex(c8 h) 1816 { 1817 if (h >= '0' && h <='9') 1818 return h-'0'; 1819 1820 if (h >= 'a' && h <='f') 1821 return h-'a' + 10; 1822 1823 return 0; 1824 } 1825 getHexStrFromByte(c8 byte,c8 * out)1826 static inline void getHexStrFromByte(c8 byte, c8* out) 1827 { 1828 s32 b = (byte & 0xf0) >> 4; 1829 1830 for (s32 i=0; i<2; ++i) 1831 { 1832 if (b >=0 && b <= 9) 1833 out[i] = b+'0'; 1834 if (b >=10 && b <= 15) 1835 out[i] = (b-10)+'a'; 1836 1837 b = byte & 0x0f; 1838 } 1839 } 1840 }; 1841 1842 // Attribute implemented for binary data 1843 class CBinaryAttribute : public CStringAttribute 1844 { 1845 public: 1846 CBinaryAttribute(const char * name,void * binaryData,s32 lenghtInBytes)1847 CBinaryAttribute(const char* name, void* binaryData, s32 lenghtInBytes) 1848 : CStringAttribute(name, binaryData, lenghtInBytes) 1849 { 1850 1851 } 1852 getType()1853 virtual E_ATTRIBUTE_TYPE getType() const 1854 { 1855 return EAT_BINARY; 1856 } 1857 1858 getTypeString()1859 virtual const wchar_t* getTypeString() const 1860 { 1861 return L"binary"; 1862 } 1863 }; 1864 1865 1866 1867 // Attribute implemented for texture references 1868 class CTextureAttribute : public IAttribute 1869 { 1870 public: 1871 CTextureAttribute(const char * name,video::ITexture * value,video::IVideoDriver * driver,const io::path & filename)1872 CTextureAttribute(const char* name, video::ITexture* value, video::IVideoDriver* driver, const io::path& filename) 1873 : Value(0), Driver(driver), OverrideName(filename) 1874 { 1875 if (Driver) 1876 Driver->grab(); 1877 1878 Name = name; 1879 setTexture(value); 1880 } 1881 ~CTextureAttribute()1882 ~CTextureAttribute() 1883 { 1884 if (Driver) 1885 Driver->drop(); 1886 1887 if (Value) 1888 Value->drop(); 1889 } 1890 getTexture()1891 virtual video::ITexture* getTexture() 1892 { 1893 return Value; 1894 } 1895 getBool()1896 virtual bool getBool() 1897 { 1898 return (Value != 0); 1899 } 1900 getStringW()1901 virtual core::stringw getStringW() 1902 { 1903 // (note: don't try to put all this in some ?: operators, or c++ builder will choke) 1904 if ( OverrideName.size() ) 1905 return core::stringw(OverrideName); 1906 1907 if ( Value ) 1908 return core::stringw(Value->getName().getPath().c_str()); 1909 1910 return core::stringw(0); 1911 } 1912 getString()1913 virtual core::stringc getString() 1914 { 1915 // since texture names can be stringw we are careful with the types 1916 if ( OverrideName.size() ) 1917 return core::stringc(OverrideName); 1918 1919 if ( Value ) 1920 return core::stringc(Value->getName().getPath().c_str()); 1921 1922 return core::stringc(0); 1923 } 1924 setString(const char * text)1925 virtual void setString(const char* text) 1926 { 1927 if (Driver) 1928 { 1929 if (text && *text) 1930 { 1931 setTexture(Driver->getTexture(text)); 1932 OverrideName=text; 1933 } 1934 else 1935 setTexture(0); 1936 } 1937 } 1938 setTexture(video::ITexture * value)1939 virtual void setTexture(video::ITexture* value) 1940 { 1941 if ( value == Value ) 1942 return; 1943 1944 if (Value) 1945 Value->drop(); 1946 1947 Value = value; 1948 1949 if (Value) 1950 Value->grab(); 1951 } 1952 getType()1953 virtual E_ATTRIBUTE_TYPE getType() const 1954 { 1955 return EAT_TEXTURE; 1956 } 1957 1958 getTypeString()1959 virtual const wchar_t* getTypeString() const 1960 { 1961 return L"texture"; 1962 } 1963 1964 video::ITexture* Value; 1965 video::IVideoDriver* Driver; 1966 io::path OverrideName; 1967 }; 1968 1969 1970 1971 // Attribute implemented for array of stringw 1972 class CStringWArrayAttribute : public IAttribute 1973 { 1974 public: 1975 CStringWArrayAttribute(const char * name,const core::array<core::stringw> & value)1976 CStringWArrayAttribute(const char* name, const core::array<core::stringw>& value) 1977 { 1978 Name = name; 1979 setArray(value); 1980 } 1981 getArray()1982 virtual core::array<core::stringw> getArray() 1983 { 1984 return Value; 1985 } 1986 setArray(const core::array<core::stringw> & value)1987 virtual void setArray(const core::array<core::stringw>& value) 1988 { 1989 Value = value; 1990 } 1991 getType()1992 virtual E_ATTRIBUTE_TYPE getType() const 1993 { 1994 return EAT_STRINGWARRAY; 1995 } 1996 getTypeString()1997 virtual const wchar_t* getTypeString() const 1998 { 1999 return L"stringwarray"; 2000 } 2001 2002 core::array<core::stringw> Value; 2003 }; 2004 2005 2006 // Attribute implemented for user pointers 2007 class CUserPointerAttribute : public IAttribute 2008 { 2009 public: 2010 CUserPointerAttribute(const char * name,void * value)2011 CUserPointerAttribute(const char* name, void* value) 2012 { 2013 Name = name; 2014 Value = value; 2015 } 2016 getInt()2017 virtual s32 getInt() 2018 { 2019 return *static_cast<s32*>(Value); 2020 } 2021 getBool()2022 virtual bool getBool() 2023 { 2024 return (Value != 0); 2025 } 2026 getStringW()2027 virtual core::stringw getStringW() 2028 { 2029 wchar_t buf[32]; 2030 swprintf(buf, 32, L"%p", Value); 2031 2032 return core::stringw(buf); 2033 } 2034 setString(const char * text)2035 virtual void setString(const char* text) 2036 { 2037 u32 tmp; 2038 sscanf(text, "0x%x", &tmp); 2039 Value = (void *) tmp; 2040 } 2041 getType()2042 virtual E_ATTRIBUTE_TYPE getType() const 2043 { 2044 return EAT_USER_POINTER; 2045 } 2046 setUserPointer(void * v)2047 virtual void setUserPointer(void* v) 2048 { 2049 Value = v; 2050 } 2051 getUserPointer()2052 virtual void* getUserPointer() 2053 { 2054 return Value; 2055 } 2056 2057 getTypeString()2058 virtual const wchar_t* getTypeString() const 2059 { 2060 return L"userPointer"; 2061 } 2062 2063 void* Value; 2064 }; 2065 2066 2067 2068 // todo: CGUIFontAttribute 2069 2070 } // end namespace io 2071 } // end namespace irr 2072