// Copyright (C) 2002-2012 Nikolaus Gebhardt // This file is part of the "Irrlicht Engine". // For conditions of distribution and use, see copyright notice in irrlicht.h #include "CAttributes.h" #include "fast_atof.h" #include "ITexture.h" #include "IVideoDriver.h" namespace irr { namespace io { /* Basic types, check documentation in IAttribute.h to see how they generally work. */ // Attribute implemented for boolean values class CBoolAttribute : public IAttribute { public: CBoolAttribute(const char* name, bool value) { Name = name; setBool(value); } virtual s32 getInt() const _IRR_OVERRIDE_ { return BoolValue ? 1 : 0; } virtual f32 getFloat() const _IRR_OVERRIDE_ { return BoolValue ? 1.0f : 0.0f; } virtual bool getBool() const _IRR_OVERRIDE_ { return BoolValue; } virtual core::stringw getStringW() const _IRR_OVERRIDE_ { return core::stringw( BoolValue ? L"true" : L"false" ); } virtual void setInt(s32 intValue) _IRR_OVERRIDE_ { BoolValue = (intValue != 0); } virtual void setFloat(f32 floatValue) _IRR_OVERRIDE_ { BoolValue = (floatValue != 0); } virtual void setBool(bool boolValue) _IRR_OVERRIDE_ { BoolValue = boolValue; } virtual void setString(const char* string) _IRR_OVERRIDE_ { BoolValue = strcmp(string, "true") == 0; } virtual E_ATTRIBUTE_TYPE getType() const _IRR_OVERRIDE_ { return EAT_BOOL; } virtual const wchar_t* getTypeString() const _IRR_OVERRIDE_ { return L"bool"; } bool BoolValue; }; // Attribute implemented for integers class CIntAttribute : public IAttribute { public: CIntAttribute(const char* name, s32 value) { Name = name; setInt(value); } virtual s32 getInt() const _IRR_OVERRIDE_ { return Value; } virtual f32 getFloat() const _IRR_OVERRIDE_ { return (f32)Value; } virtual bool getBool() const _IRR_OVERRIDE_ { return (Value != 0); } virtual core::stringw getStringW() const _IRR_OVERRIDE_ { return core::stringw(Value); } virtual void setInt(s32 intValue) _IRR_OVERRIDE_ { Value = intValue; } virtual void setFloat(f32 floatValue) _IRR_OVERRIDE_ { Value = (s32)floatValue; }; virtual void setString(const char* text) _IRR_OVERRIDE_ { Value = atoi(text); } virtual E_ATTRIBUTE_TYPE getType() const _IRR_OVERRIDE_ { return EAT_INT; } virtual const wchar_t* getTypeString() const _IRR_OVERRIDE_ { return L"int"; } s32 Value; }; // Attribute implemented for floats class CFloatAttribute : public IAttribute { public: CFloatAttribute(const char* name, f32 value) { Name = name; setFloat(value); } virtual s32 getInt() const _IRR_OVERRIDE_ { return (s32)Value; } virtual f32 getFloat() const _IRR_OVERRIDE_ { return Value; } virtual bool getBool() const _IRR_OVERRIDE_ { return (Value != 0); } virtual core::stringw getStringW() const _IRR_OVERRIDE_ { return core::stringw((double)Value); } virtual void setInt(s32 intValue) _IRR_OVERRIDE_ { Value = (f32)intValue; } virtual void setFloat(f32 floatValue) _IRR_OVERRIDE_ { Value = floatValue; } virtual void setString(const char* text) _IRR_OVERRIDE_ { Value = core::fast_atof(text); } virtual E_ATTRIBUTE_TYPE getType() const _IRR_OVERRIDE_ { return EAT_FLOAT; } virtual const wchar_t* getTypeString() const _IRR_OVERRIDE_ { return L"float"; } f32 Value; }; /* Types which can be represented as a list of numbers */ // Base class for all attributes which are a list of numbers- // vectors, colors, positions, triangles, etc class CNumbersAttribute : public IAttribute { public: CNumbersAttribute(const char* name, video::SColorf value) : ValueI(), ValueF(), Count(4), IsFloat(true) { Name = name; ValueF.push_back(value.r); ValueF.push_back(value.g); ValueF.push_back(value.b); ValueF.push_back(value.a); } CNumbersAttribute(const char* name, video::SColor value) : ValueI(), ValueF(), Count(4), IsFloat(false) { Name = name; ValueI.push_back(value.getRed()); ValueI.push_back(value.getGreen()); ValueI.push_back(value.getBlue()); ValueI.push_back(value.getAlpha()); } CNumbersAttribute(const char* name, const core::vector3df& value) : ValueI(), ValueF(), Count(3), IsFloat(true) { Name = name; ValueF.push_back(value.X); ValueF.push_back(value.Y); ValueF.push_back(value.Z); } CNumbersAttribute(const char* name, const core::rect& value) : ValueI(), ValueF(), Count(4), IsFloat(false) { Name = name; ValueI.push_back(value.UpperLeftCorner.X); ValueI.push_back(value.UpperLeftCorner.Y); ValueI.push_back(value.LowerRightCorner.X); ValueI.push_back(value.LowerRightCorner.Y); } CNumbersAttribute(const char* name, const core::rect& value) : ValueI(), ValueF(), Count(4), IsFloat(true) { Name = name; ValueF.push_back(value.UpperLeftCorner.X); ValueF.push_back(value.UpperLeftCorner.Y); ValueF.push_back(value.LowerRightCorner.X); ValueF.push_back(value.LowerRightCorner.Y); } CNumbersAttribute(const char* name, const core::matrix4& value) : ValueI(), ValueF(), Count(16), IsFloat(true) { Name = name; for (s32 r=0; r<4; ++r) for (s32 c=0; c<4; ++c) ValueF.push_back(value(r,c)); } CNumbersAttribute(const char* name, const core::quaternion& value) : ValueI(), ValueF(), Count(4), IsFloat(true) { Name = name; ValueF.push_back(value.X); ValueF.push_back(value.Y); ValueF.push_back(value.Z); ValueF.push_back(value.W); } CNumbersAttribute(const char* name, const core::aabbox3d& value) : ValueI(), ValueF(), Count(6), IsFloat(true) { Name = name; ValueF.push_back(value.MinEdge.X); ValueF.push_back(value.MinEdge.Y); ValueF.push_back(value.MinEdge.Z); ValueF.push_back(value.MaxEdge.X); ValueF.push_back(value.MaxEdge.Y); ValueF.push_back(value.MaxEdge.Z); } CNumbersAttribute(const char* name, const core::plane3df& value) : ValueI(), ValueF(), Count(4), IsFloat(true) { Name = name; ValueF.push_back(value.Normal.X); ValueF.push_back(value.Normal.Y); ValueF.push_back(value.Normal.Z); ValueF.push_back(value.D); } CNumbersAttribute(const char* name, const core::triangle3df& value) : ValueI(), ValueF(), Count(9), IsFloat(true) { Name = name; ValueF.push_back(value.pointA.X); ValueF.push_back(value.pointA.Y); ValueF.push_back(value.pointA.Z); ValueF.push_back(value.pointB.X); ValueF.push_back(value.pointB.Y); ValueF.push_back(value.pointB.Z); ValueF.push_back(value.pointC.X); ValueF.push_back(value.pointC.Y); ValueF.push_back(value.pointC.Z); } CNumbersAttribute(const char* name, const core::vector2df& value) : ValueI(), ValueF(), Count(2), IsFloat(true) { Name = name; ValueF.push_back(value.X); ValueF.push_back(value.Y); } CNumbersAttribute(const char* name, const core::vector2di& value) : ValueI(), ValueF(), Count(2), IsFloat(false) { Name = name; ValueI.push_back(value.X); ValueI.push_back(value.Y); } CNumbersAttribute(const char* name, const core::line2di& value) : ValueI(), ValueF(), Count(4), IsFloat(false) { Name = name; ValueI.push_back(value.start.X); ValueI.push_back(value.start.Y); ValueI.push_back(value.end.X); ValueI.push_back(value.end.Y); } CNumbersAttribute(const char* name, const core::line2df& value) : ValueI(), ValueF(), Count(4), IsFloat(true) { Name = name; ValueF.push_back(value.start.X); ValueF.push_back(value.start.Y); ValueF.push_back(value.end.X); ValueF.push_back(value.end.Y); } CNumbersAttribute(const char* name, const core::line3df& value) : ValueI(), ValueF(), Count(6), IsFloat(true) { Name = name; ValueF.push_back(value.start.X); ValueF.push_back(value.start.Y); ValueF.push_back(value.start.Z); ValueF.push_back(value.end.X); ValueF.push_back(value.end.Y); ValueF.push_back(value.end.Z); } CNumbersAttribute(const char* name, const core::dimension2du& value) : ValueI(), ValueF(), Count(2), IsFloat(false) { Name = name; ValueI.push_back(value.Width); ValueI.push_back(value.Height); } CNumbersAttribute(const char* name, const core::dimension2df& value) : ValueI(), ValueF(), Count(2), IsFloat(true) { Name = name; ValueF.push_back(value.Width); ValueF.push_back(value.Height); } // getting values virtual s32 getInt() const _IRR_OVERRIDE_ { if (Count==0) return 0; if (IsFloat) return (s32)ValueF[0]; else return ValueI[0]; } virtual f32 getFloat() const _IRR_OVERRIDE_ { if (Count==0) return 0.0f; if (IsFloat) return ValueF[0]; else return (f32)ValueI[0]; } virtual bool getBool() const _IRR_OVERRIDE_ { // return true if any number is nonzero bool ret=false; for (u32 i=0; i < Count; ++i) if ( IsFloat ? (ValueF[i] != 0) : (ValueI[i] != 0) ) { ret=true; break; } return ret; } virtual core::stringc getString() const _IRR_OVERRIDE_ { core::stringc outstr; for (u32 i=0; i 0 ? ValueF[0] : 0); p.Y = (s32)(Count > 1 ? ValueF[1] : 0); } else { p.X = Count > 0 ? ValueI[0] : 0; p.Y = Count > 1 ? ValueI[1] : 0; } return p; } virtual core::vector3df getVector() const _IRR_OVERRIDE_ { core::vector3df v; if (IsFloat) { v.X = Count > 0 ? ValueF[0] : 0; v.Y = Count > 1 ? ValueF[1] : 0; v.Z = Count > 2 ? ValueF[2] : 0; } else { v.X = (f32)(Count > 0 ? ValueI[0] : 0); v.Y = (f32)(Count > 1 ? ValueI[1] : 0); v.Z = (f32)(Count > 2 ? ValueI[2] : 0); } return v; } virtual core::vector2df getVector2d() const _IRR_OVERRIDE_ { core::vector2df v; if (IsFloat) { v.X = Count > 0 ? ValueF[0] : 0; v.Y = Count > 1 ? ValueF[1] : 0; } else { v.X = (f32)(Count > 0 ? ValueI[0] : 0); v.Y = (f32)(Count > 1 ? ValueI[1] : 0); } return v; } virtual video::SColorf getColorf() const _IRR_OVERRIDE_ { video::SColorf c; if (IsFloat) { c.setColorComponentValue(0, Count > 0 ? ValueF[0] : 0); c.setColorComponentValue(1, Count > 1 ? ValueF[1] : 0); c.setColorComponentValue(2, Count > 2 ? ValueF[2] : 0); c.setColorComponentValue(3, Count > 3 ? ValueF[3] : 0); } else { c.setColorComponentValue(0, Count > 0 ? (f32)(ValueI[0]) / 255.0f : 0); c.setColorComponentValue(1, Count > 1 ? (f32)(ValueI[1]) / 255.0f : 0); c.setColorComponentValue(2, Count > 2 ? (f32)(ValueI[2]) / 255.0f : 0); c.setColorComponentValue(3, Count > 3 ? (f32)(ValueI[3]) / 255.0f : 0); } return c; } virtual video::SColor getColor() const _IRR_OVERRIDE_ { return getColorf().toSColor(); } virtual core::rect getRect() const _IRR_OVERRIDE_ { core::rect r; if (IsFloat) { r.UpperLeftCorner.X = (s32)(Count > 0 ? ValueF[0] : 0); r.UpperLeftCorner.Y = (s32)(Count > 1 ? ValueF[1] : 0); r.LowerRightCorner.X = (s32)(Count > 2 ? ValueF[2] : r.UpperLeftCorner.X); r.LowerRightCorner.Y = (s32)(Count > 3 ? ValueF[3] : r.UpperLeftCorner.Y); } else { r.UpperLeftCorner.X = Count > 0 ? ValueI[0] : 0; r.UpperLeftCorner.Y = Count > 1 ? ValueI[1] : 0; r.LowerRightCorner.X = Count > 2 ? ValueI[2] : r.UpperLeftCorner.X; r.LowerRightCorner.Y = Count > 3 ? ValueI[3] : r.UpperLeftCorner.Y; } return r; } virtual core::dimension2du getDimension2d() const _IRR_OVERRIDE_ { core::dimension2d dim; if (IsFloat) { dim.Width = (u32)(Count > 0 ? ValueF[0] : 0); dim.Height = (u32)(Count > 1 ? ValueF[1] : 0); } else { dim.Width = (u32)(Count > 0 ? ValueI[0] : 0); dim.Height = (u32)(Count > 1 ? ValueI[1] : 0); } return dim; } virtual core::matrix4 getMatrix() const _IRR_OVERRIDE_ { core::matrix4 ret; if (IsFloat) { for (u32 r=0; r<4; ++r) for (u32 c=0; c<4; ++c) if (Count > c+r*4) ret(r,c) = ValueF[c+r*4]; } else { for (u32 r=0; r<4; ++r) for (u32 c=0; c<4; ++c) if (Count > c+r*4) ret(r,c) = (f32)ValueI[c+r*4]; } return ret; } virtual core::quaternion getQuaternion() const _IRR_OVERRIDE_ { core::quaternion ret; if (IsFloat) { ret.X = Count > 0 ? ValueF[0] : 0.0f; ret.Y = Count > 1 ? ValueF[1] : 0.0f; ret.Z = Count > 2 ? ValueF[2] : 0.0f; ret.W = Count > 3 ? ValueF[3] : 0.0f; } else { ret.X = Count > 0 ? (f32)ValueI[0] : 0.0f; ret.Y = Count > 1 ? (f32)ValueI[1] : 0.0f; ret.Z = Count > 2 ? (f32)ValueI[2] : 0.0f; ret.W = Count > 3 ? (f32)ValueI[3] : 0.0f; } return ret; } virtual core::triangle3df getTriangle() const _IRR_OVERRIDE_ { core::triangle3df ret; if (IsFloat) { ret.pointA.X = Count > 0 ? ValueF[0] : 0.0f; ret.pointA.Y = Count > 1 ? ValueF[1] : 0.0f; ret.pointA.Z = Count > 2 ? ValueF[2] : 0.0f; ret.pointB.X = Count > 3 ? ValueF[3] : 0.0f; ret.pointB.Y = Count > 4 ? ValueF[4] : 0.0f; ret.pointB.Z = Count > 5 ? ValueF[5] : 0.0f; ret.pointC.X = Count > 6 ? ValueF[6] : 0.0f; ret.pointC.Y = Count > 7 ? ValueF[7] : 0.0f; ret.pointC.Z = Count > 8 ? ValueF[8] : 0.0f; } else { ret.pointA.X = Count > 0 ? (f32)ValueI[0] : 0.0f; ret.pointA.Y = Count > 1 ? (f32)ValueI[1] : 0.0f; ret.pointA.Z = Count > 2 ? (f32)ValueI[2] : 0.0f; ret.pointB.X = Count > 3 ? (f32)ValueI[3] : 0.0f; ret.pointB.Y = Count > 4 ? (f32)ValueI[4] : 0.0f; ret.pointB.Z = Count > 5 ? (f32)ValueI[5] : 0.0f; ret.pointC.X = Count > 6 ? (f32)ValueI[6] : 0.0f; ret.pointC.Y = Count > 7 ? (f32)ValueI[7] : 0.0f; ret.pointC.Z = Count > 8 ? (f32)ValueI[8] : 0.0f; } return ret; } virtual core::plane3df getPlane() const _IRR_OVERRIDE_ { core::plane3df ret; if (IsFloat) { ret.Normal.X = Count > 0 ? ValueF[0] : 0.0f; ret.Normal.Y = Count > 1 ? ValueF[1] : 0.0f; ret.Normal.Z = Count > 2 ? ValueF[2] : 0.0f; ret.D = Count > 3 ? ValueF[3] : 0.0f; } else { ret.Normal.X = Count > 0 ? (f32)ValueI[0] : 0.0f; ret.Normal.Y = Count > 1 ? (f32)ValueI[1] : 0.0f; ret.Normal.Z = Count > 2 ? (f32)ValueI[2] : 0.0f; ret.D = Count > 3 ? (f32)ValueI[3] : 0.0f; } return ret; } virtual core::aabbox3df getBBox() const _IRR_OVERRIDE_ { core::aabbox3df ret; if (IsFloat) { ret.MinEdge.X = Count > 0 ? ValueF[0] : 0.0f; ret.MinEdge.Y = Count > 1 ? ValueF[1] : 0.0f; ret.MinEdge.Z = Count > 2 ? ValueF[2] : 0.0f; ret.MaxEdge.X = Count > 3 ? ValueF[3] : 0.0f; ret.MaxEdge.Y = Count > 4 ? ValueF[4] : 0.0f; ret.MaxEdge.Z = Count > 5 ? ValueF[5] : 0.0f; } else { ret.MinEdge.X = Count > 0 ? (f32)ValueI[0] : 0.0f; ret.MinEdge.Y = Count > 1 ? (f32)ValueI[1] : 0.0f; ret.MinEdge.Z = Count > 2 ? (f32)ValueI[2] : 0.0f; ret.MaxEdge.X = Count > 3 ? (f32)ValueI[3] : 0.0f; ret.MaxEdge.Y = Count > 4 ? (f32)ValueI[4] : 0.0f; ret.MaxEdge.Z = Count > 5 ? (f32)ValueI[5] : 0.0f; } return ret; } virtual core::line2df getLine2d() const _IRR_OVERRIDE_ { core::line2df ret; if (IsFloat) { ret.start.X = Count > 0 ? ValueF[0] : 0.0f; ret.start.Y = Count > 1 ? ValueF[1] : 0.0f; ret.end.X = Count > 2 ? ValueF[2] : 0.0f; ret.end.Y = Count > 3 ? ValueF[3] : 0.0f; } else { ret.start.X = Count > 0 ? (f32)ValueI[0] : 0.0f; ret.start.Y = Count > 1 ? (f32)ValueI[1] : 0.0f; ret.end.X = Count > 2 ? (f32)ValueI[2] : 0.0f; ret.end.Y = Count > 3 ? (f32)ValueI[3] : 0.0f; } return ret; } virtual core::line3df getLine3d() const _IRR_OVERRIDE_ { core::line3df ret; if (IsFloat) { ret.start.X = Count > 0 ? ValueF[0] : 0.0f; ret.start.Y = Count > 1 ? ValueF[1] : 0.0f; ret.start.Z = Count > 2 ? ValueF[2] : 0.0f; ret.end.X = Count > 3 ? ValueF[3] : 0.0f; ret.end.Y = Count > 4 ? ValueF[4] : 0.0f; ret.end.Z = Count > 5 ? ValueF[5] : 0.0f; } else { ret.start.X = Count > 0 ? (f32)ValueI[0] : 0.0f; ret.start.Y = Count > 1 ? (f32)ValueI[1] : 0.0f; ret.start.Z = Count > 2 ? (f32)ValueI[2] : 0.0f; ret.end.X = Count > 3 ? (f32)ValueI[3] : 0.0f; ret.end.Y = Count > 4 ? (f32)ValueI[4] : 0.0f; ret.end.Z = Count > 5 ? (f32)ValueI[5] : 0.0f; } return ret; } //! get float array virtual core::array getFloatArray() { if (!IsFloat) { ValueF.clear(); for (u32 i=0; i getIntArray() { if (IsFloat) { ValueI.clear(); for (u32 i=0; i '9') ) ) ++P; // set value if ( *P) { if (IsFloat) { f32 c = 0; P = core::fast_atof_move(P, c); ValueF[i] = c; } else { // todo: fix this to read ints properly f32 c = 0; P = core::fast_atof_move(P, c); ValueI[i] = (s32)c; } } } // todo: warning message //if (i < Count-1) //{ // //} } virtual void setPosition(const core::position2di& v) _IRR_OVERRIDE_ { reset(); if (IsFloat) { if (Count > 0) ValueF[0] = (f32)v.X; if (Count > 1) ValueF[1] = (f32)v.Y; } else { if (Count > 0) ValueI[0] = v.X; if (Count > 1) ValueI[1] = v.Y; } } virtual void setVector(const core::vector3df& v) _IRR_OVERRIDE_ { reset(); if (IsFloat) { if (Count > 0) ValueF[0] = v.X; if (Count > 1) ValueF[1] = v.Y; if (Count > 2) ValueF[2] = v.Z; } else { if (Count > 0) ValueI[0] = (s32)v.X; if (Count > 1) ValueI[1] = (s32)v.Y; if (Count > 2) ValueI[2] = (s32)v.Z; } } virtual void setColor(video::SColorf color) _IRR_OVERRIDE_ { reset(); if (IsFloat) { if (Count > 0) ValueF[0] = color.r; if (Count > 1) ValueF[1] = color.g; if (Count > 2) ValueF[2] = color.b; if (Count > 3) ValueF[3] = color.a; } else { if (Count > 0) ValueI[0] = (s32)(color.r * 255); if (Count > 1) ValueI[1] = (s32)(color.g * 255); if (Count > 2) ValueI[2] = (s32)(color.b * 255); if (Count > 3) ValueI[3] = (s32)(color.a * 255); } } virtual void setColor(video::SColor color) _IRR_OVERRIDE_ { reset(); if (IsFloat) { if (Count > 0) ValueF[0] = (f32)color.getRed() / 255.0f; if (Count > 1) ValueF[1] = (f32)color.getGreen() / 255.0f; if (Count > 2) ValueF[2] = (f32)color.getBlue() / 255.0f; if (Count > 3) ValueF[3] = (f32)color.getAlpha() / 255.0f; } else { if (Count > 0) ValueI[0] = color.getRed(); if (Count > 1) ValueI[1] = color.getGreen(); if (Count > 2) ValueI[2] = color.getBlue(); if (Count > 3) ValueI[3] = color.getAlpha(); } } virtual void setRect(const core::rect& value) _IRR_OVERRIDE_ { reset(); if (IsFloat) { if (Count > 0) ValueF[0] = (f32)value.UpperLeftCorner.X; if (Count > 1) ValueF[1] = (f32)value.UpperLeftCorner.Y; if (Count > 2) ValueF[2] = (f32)value.LowerRightCorner.X; if (Count > 3) ValueF[3] = (f32)value.LowerRightCorner.Y; } else { if (Count > 0) ValueI[0] = value.UpperLeftCorner.X; if (Count > 1) ValueI[1] = value.UpperLeftCorner.Y; if (Count > 2) ValueI[2] = value.LowerRightCorner.X; if (Count > 3) ValueI[3] = value.LowerRightCorner.Y; } } virtual void setMatrix(const core::matrix4& value) _IRR_OVERRIDE_ { reset(); if (IsFloat) { for (u32 r=0; r<4; ++r) for (u32 c=0; c<4; ++c) if (Count > c+r*4) ValueF[c+r*4] = value(r,c); } else { for (u32 r=0; r<4; ++r) for (u32 c=0; c<4; ++c) if (Count > c+r*4) ValueI[c+r*4] = (s32)value(r,c); } } virtual void setQuaternion(const core::quaternion& value) _IRR_OVERRIDE_ { reset(); if (IsFloat) { if (Count > 0) ValueF[0] = value.X; if (Count > 1) ValueF[1] = value.Y; if (Count > 2) ValueF[2] = value.Z; if (Count > 3) ValueF[3] = value.W; } else { if (Count > 0) ValueI[0] = (s32)value.X; if (Count > 1) ValueI[1] = (s32)value.Y; if (Count > 2) ValueI[2] = (s32)value.Z; if (Count > 3) ValueI[3] = (s32)value.W; } } virtual void setBoundingBox(const core::aabbox3d& value) { reset(); if (IsFloat) { if (Count > 0) ValueF[0] = value.MinEdge.X; if (Count > 1) ValueF[1] = value.MinEdge.Y; if (Count > 2) ValueF[2] = value.MinEdge.Z; if (Count > 3) ValueF[3] = value.MaxEdge.X; if (Count > 4) ValueF[4] = value.MaxEdge.Y; if (Count > 5) ValueF[5] = value.MaxEdge.Z; } else { if (Count > 0) ValueI[0] = (s32)value.MinEdge.X; if (Count > 1) ValueI[1] = (s32)value.MinEdge.Y; if (Count > 2) ValueI[2] = (s32)value.MinEdge.Z; if (Count > 3) ValueI[3] = (s32)value.MaxEdge.X; if (Count > 4) ValueI[4] = (s32)value.MaxEdge.Y; if (Count > 5) ValueI[5] = (s32)value.MaxEdge.Z; } } virtual void setPlane(const core::plane3df& value) _IRR_OVERRIDE_ { reset(); if (IsFloat) { if (Count > 0) ValueF[0] = value.Normal.X; if (Count > 1) ValueF[1] = value.Normal.Y; if (Count > 2) ValueF[2] = value.Normal.Z; if (Count > 3) ValueF[3] = value.D; } else { if (Count > 0) ValueI[0] = (s32)value.Normal.X; if (Count > 1) ValueI[1] = (s32)value.Normal.Y; if (Count > 2) ValueI[2] = (s32)value.Normal.Z; if (Count > 3) ValueI[3] = (s32)value.D; } } virtual void setTriangle3d(const core::triangle3df& value) { reset(); if (IsFloat) { if (Count > 0) ValueF[0] = value.pointA.X; if (Count > 1) ValueF[1] = value.pointA.Y; if (Count > 2) ValueF[2] = value.pointA.Z; if (Count > 3) ValueF[3] = value.pointB.X; if (Count > 4) ValueF[4] = value.pointB.Y; if (Count > 5) ValueF[5] = value.pointB.Z; if (Count > 6) ValueF[6] = value.pointC.X; if (Count > 7) ValueF[7] = value.pointC.Y; if (Count > 8) ValueF[8] = value.pointC.Z; } else { if (Count > 0) ValueI[0] = (s32)value.pointA.X; if (Count > 1) ValueI[1] = (s32)value.pointA.Y; if (Count > 2) ValueI[2] = (s32)value.pointA.Z; if (Count > 3) ValueI[3] = (s32)value.pointB.X; if (Count > 4) ValueI[4] = (s32)value.pointB.Y; if (Count > 5) ValueI[5] = (s32)value.pointB.Z; if (Count > 6) ValueI[6] = (s32)value.pointC.X; if (Count > 7) ValueI[7] = (s32)value.pointC.Y; if (Count > 8) ValueI[8] = (s32)value.pointC.Z; } } virtual void setVector2d(const core::vector2df& v) _IRR_OVERRIDE_ { reset(); if (IsFloat) { if (Count > 0) ValueF[0] = v.X; if (Count > 1) ValueF[1] = v.Y; } else { if (Count > 0) ValueI[0] = (s32)v.X; if (Count > 1) ValueI[1] = (s32)v.Y; } } virtual void setVector2d(const core::vector2di& v) _IRR_OVERRIDE_ { reset(); if (IsFloat) { if (Count > 0) ValueF[0] = (f32)v.X; if (Count > 1) ValueF[1] = (f32)v.Y; } else { if (Count > 0) ValueI[0] = v.X; if (Count > 1) ValueI[1] = v.Y; } } virtual void setLine2d(const core::line2di& v) _IRR_OVERRIDE_ { reset(); if (IsFloat) { if (Count > 0) ValueF[0] = (f32)v.start.X; if (Count > 1) ValueF[1] = (f32)v.start.Y; if (Count > 2) ValueF[2] = (f32)v.end.X; if (Count > 3) ValueF[3] = (f32)v.end.Y; } else { if (Count > 0) ValueI[0] = v.start.X; if (Count > 1) ValueI[1] = v.start.Y; if (Count > 2) ValueI[2] = v.end.X; if (Count > 3) ValueI[3] = v.end.Y; } } virtual void setLine2d(const core::line2df& v) _IRR_OVERRIDE_ { reset(); if (IsFloat) { if (Count > 0) ValueF[0] = v.start.X; if (Count > 1) ValueF[1] = v.start.Y; if (Count > 2) ValueF[2] = v.end.X; if (Count > 3) ValueF[3] = v.end.Y; } else { if (Count > 0) ValueI[0] = (s32)v.start.X; if (Count > 1) ValueI[1] = (s32)v.start.Y; if (Count > 2) ValueI[2] = (s32)v.end.X; if (Count > 3) ValueI[3] = (s32)v.end.Y; } } virtual void setDimension2d(const core::dimension2du& v) _IRR_OVERRIDE_ { reset(); if (IsFloat) { if (Count > 0) ValueF[0] = (f32)v.Width; if (Count > 1) ValueF[1] = (f32)v.Height; } else { if (Count > 0) ValueI[0] = (s32)v.Width; if (Count > 1) ValueI[1] = (s32)v.Height; } } //! set float array virtual void setFloatArray(core::array &vals) { reset(); for (u32 i=0; i &vals) { reset(); for (u32 i=0; i ValueI; core::array ValueF; u32 Count; bool IsFloat; }; // Attribute implemented for floating point colors class CColorfAttribute : public CNumbersAttribute { public: CColorfAttribute(const char* name, video::SColorf value) : CNumbersAttribute(name, value) {} virtual s32 getInt() const _IRR_OVERRIDE_ { return getColor().color; } virtual f32 getFloat() const _IRR_OVERRIDE_ { return (f32)getColor().color; } virtual void setInt(s32 intValue) _IRR_OVERRIDE_ { video::SColorf c = video::SColor(intValue); ValueF[0] = c.r; ValueF[1] = c.g; ValueF[2] = c.b; ValueF[3] = c.a; } virtual void setFloat(f32 floatValue) _IRR_OVERRIDE_ { setInt((s32)floatValue); } virtual E_ATTRIBUTE_TYPE getType() const _IRR_OVERRIDE_ { return EAT_COLORF; } virtual const wchar_t* getTypeString() const _IRR_OVERRIDE_ { return L"colorf"; } }; // Attribute implemented for colors class CColorAttribute : public CNumbersAttribute { public: CColorAttribute(const char* name, const video::SColorf& value) : CNumbersAttribute(name, value) {} CColorAttribute(const char* name, const video::SColor& value) : CNumbersAttribute(name, value) {} virtual s32 getInt() const _IRR_OVERRIDE_ { return getColor().color; } virtual f32 getFloat() const _IRR_OVERRIDE_ { return (f32)getColor().color; } virtual void setInt(s32 intValue) _IRR_OVERRIDE_ { video::SColorf c = video::SColor(intValue); ValueF[0] = c.r; ValueF[1] = c.g; ValueF[2] = c.b; ValueF[3] = c.a; } virtual void setFloat(f32 floatValue) _IRR_OVERRIDE_ { setInt((s32)floatValue); } virtual core::stringc getString() const _IRR_OVERRIDE_ { char tmp[10]; const video::SColor c = getColor(); sprintf(tmp, "%02x%02x%02x%02x", c.getAlpha(), c.getRed(), c.getGreen(), c.getBlue()); return core::stringc(tmp); } virtual core::stringw getStringW() const _IRR_OVERRIDE_ { char tmp[10]; const video::SColor c = getColor(); sprintf(tmp, "%02x%02x%02x%02x", c.getAlpha(), c.getRed(), c.getGreen(), c.getBlue()); return core::stringw(tmp); } virtual void setString(const char* text) _IRR_OVERRIDE_ { u32 c; int characters; const int items = sscanf(text, "%08x%n", &c, &characters); if (items != 1 || characters != 8 ) { CNumbersAttribute::setString(text); } else setColor(c); } virtual E_ATTRIBUTE_TYPE getType() const _IRR_OVERRIDE_ { return EAT_COLOR; } virtual const wchar_t* getTypeString() const _IRR_OVERRIDE_ { return L"color"; } }; // Attribute implemented for 3d vectors class CVector3DAttribute : public CNumbersAttribute { public: CVector3DAttribute(const char* name, const core::vector3df& value) : CNumbersAttribute(name, value) {} virtual E_ATTRIBUTE_TYPE getType() const _IRR_OVERRIDE_ { return EAT_VECTOR3D; } virtual core::matrix4 getMatrix() const _IRR_OVERRIDE_ { core::matrix4 ret; ret.makeIdentity(); ret.setTranslation( core::vector3df(ValueF[0],ValueF[1],ValueF[2]) ); return ret; } virtual const wchar_t* getTypeString() const _IRR_OVERRIDE_ { return L"vector3d"; } }; // Attribute implemented for 2d vectors class CVector2DAttribute : public CNumbersAttribute { public: CVector2DAttribute(const char* name, const core::vector2df& value) : CNumbersAttribute(name, value) {} virtual E_ATTRIBUTE_TYPE getType() const _IRR_OVERRIDE_ { return EAT_VECTOR2D; } virtual const wchar_t* getTypeString() const _IRR_OVERRIDE_ { return L"vector2d"; } }; // Attribute implemented for 2d vectors class CPosition2DAttribute : public CNumbersAttribute { public: CPosition2DAttribute(const char* name, const core::position2di& value) : CNumbersAttribute(name, value) {} virtual E_ATTRIBUTE_TYPE getType() const _IRR_OVERRIDE_ { return EAT_POSITION2D; } virtual const wchar_t* getTypeString() const _IRR_OVERRIDE_ { return L"position"; } }; // Attribute implemented for rectangles class CRectAttribute : public CNumbersAttribute { public: CRectAttribute(const char* name, const core::rect& value) : CNumbersAttribute(name, value) { } virtual E_ATTRIBUTE_TYPE getType() const _IRR_OVERRIDE_ { return EAT_RECT; } virtual const wchar_t* getTypeString() const _IRR_OVERRIDE_ { return L"rect"; } }; // Attribute implemented for dimension class CDimension2dAttribute : public CNumbersAttribute { public: CDimension2dAttribute (const char* name, const core::dimension2d& value) : CNumbersAttribute(name, value) { } virtual E_ATTRIBUTE_TYPE getType() const _IRR_OVERRIDE_ { return EAT_DIMENSION2D; } virtual const wchar_t* getTypeString() const _IRR_OVERRIDE_ { return L"dimension2d"; } }; // Attribute implemented for matrices class CMatrixAttribute : public CNumbersAttribute { public: CMatrixAttribute(const char* name, const core::matrix4& value) : CNumbersAttribute(name, value) { } virtual E_ATTRIBUTE_TYPE getType() const _IRR_OVERRIDE_ { return EAT_MATRIX; } virtual core::quaternion getQuaternion() const _IRR_OVERRIDE_ { return core::quaternion(getMatrix()); } virtual const wchar_t* getTypeString() const _IRR_OVERRIDE_ { return L"matrix"; } }; // Attribute implemented for quaternions class CQuaternionAttribute : public CNumbersAttribute { public: CQuaternionAttribute(const char* name, const core::quaternion& value) : CNumbersAttribute(name, value) { } virtual E_ATTRIBUTE_TYPE getType() const _IRR_OVERRIDE_ { return EAT_QUATERNION; } virtual core::matrix4 getMatrix() const _IRR_OVERRIDE_ { return getQuaternion().getMatrix(); } virtual const wchar_t* getTypeString() const _IRR_OVERRIDE_ { return L"quaternion"; } }; // Attribute implemented for bounding boxes class CBBoxAttribute : public CNumbersAttribute { public: CBBoxAttribute(const char* name, const core::aabbox3df& value) : CNumbersAttribute(name, value) { } virtual E_ATTRIBUTE_TYPE getType() const _IRR_OVERRIDE_ { return EAT_BBOX; } virtual const wchar_t* getTypeString() const _IRR_OVERRIDE_ { return L"box3d"; } }; // Attribute implemented for planes class CPlaneAttribute : public CNumbersAttribute { public: CPlaneAttribute(const char* name, const core::plane3df& value) : CNumbersAttribute(name, value) { } virtual E_ATTRIBUTE_TYPE getType() const _IRR_OVERRIDE_ { return EAT_PLANE; } virtual const wchar_t* getTypeString() const _IRR_OVERRIDE_ { return L"plane"; } }; // Attribute implemented for triangles class CTriangleAttribute : public CNumbersAttribute { public: CTriangleAttribute(const char* name, const core::triangle3df& value) : CNumbersAttribute(name, value) { } virtual E_ATTRIBUTE_TYPE getType() const _IRR_OVERRIDE_ { return EAT_TRIANGLE3D; } virtual core::plane3df getPlane() const _IRR_OVERRIDE_ { return getTriangle().getPlane(); } virtual const wchar_t* getTypeString() const _IRR_OVERRIDE_ { return L"triangle"; } }; // Attribute implemented for 2d lines class CLine2dAttribute : public CNumbersAttribute { public: CLine2dAttribute(const char* name, const core::line2df& value) : CNumbersAttribute(name, value) { } virtual E_ATTRIBUTE_TYPE getType() const _IRR_OVERRIDE_ { return EAT_LINE2D; } virtual const wchar_t* getTypeString() const _IRR_OVERRIDE_ { return L"line2d"; } }; // Attribute implemented for 3d lines class CLine3dAttribute : public CNumbersAttribute { public: CLine3dAttribute(const char* name, const core::line3df& value) : CNumbersAttribute(name, value) { } virtual E_ATTRIBUTE_TYPE getType() const _IRR_OVERRIDE_ { return EAT_LINE3D; } virtual const wchar_t* getTypeString() const _IRR_OVERRIDE_ { return L"line3d"; } }; // vector2df // dimension2du /* Special attributes */ // Attribute implemented for enumeration literals class CEnumAttribute : public IAttribute { public: CEnumAttribute(const char* name, const char* value, const char* const* literals) { Name = name; setEnum(value, literals); } virtual void setEnum(const char* enumValue, const char* const* enumerationLiterals) _IRR_OVERRIDE_ { u32 literalCount = 0; if (enumerationLiterals) { s32 i; for (i=0; enumerationLiterals[i]; ++i) ++literalCount; EnumLiterals.reallocate(literalCount); for (i=0; enumerationLiterals[i]; ++i) EnumLiterals.push_back(enumerationLiterals[i]); } setString(enumValue); } virtual s32 getInt() const _IRR_OVERRIDE_ { for (u32 i=0; i < EnumLiterals.size(); ++i) { if (Value.equals_ignore_case(EnumLiterals[i])) { return (s32)i; } } return -1; } virtual f32 getFloat() const _IRR_OVERRIDE_ { return (f32)getInt(); } virtual bool getBool() const _IRR_OVERRIDE_ { return (getInt() != 0); // does not make a lot of sense, I know } virtual core::stringc getString() const _IRR_OVERRIDE_ { return Value; } virtual core::stringw getStringW() const _IRR_OVERRIDE_ { return core::stringw(Value.c_str()); } virtual void setInt(s32 intValue) _IRR_OVERRIDE_ { if (intValue>=0 && intValue<(s32)EnumLiterals.size()) Value = EnumLiterals[intValue]; else Value = ""; } virtual void setFloat(f32 floatValue) _IRR_OVERRIDE_ { setInt((s32)floatValue); }; virtual void setString(const char* text) _IRR_OVERRIDE_ { Value = text; } virtual const char* getEnum() const _IRR_OVERRIDE_ { return Value.c_str(); } virtual E_ATTRIBUTE_TYPE getType() const _IRR_OVERRIDE_ { return EAT_ENUM; } virtual const wchar_t* getTypeString() const _IRR_OVERRIDE_ { return L"enum"; } core::stringc Value; core::array EnumLiterals; }; // Attribute implemented for strings class CStringAttribute : public IAttribute { public: CStringAttribute(const char* name, const char* value) { IsStringW=false; Name = name; setString(value); } CStringAttribute(const char* name, const wchar_t* value) { IsStringW = true; Name = name; setString(value); } CStringAttribute(const char* name, void* binaryData, s32 lengthInBytes) { IsStringW=false; Name = name; setBinary(binaryData, lengthInBytes); } virtual s32 getInt() const _IRR_OVERRIDE_ { if (IsStringW) return atoi(core::stringc(ValueW.c_str()).c_str()); else return atoi(Value.c_str()); } virtual f32 getFloat() const _IRR_OVERRIDE_ { if (IsStringW) return core::fast_atof(core::stringc(ValueW.c_str()).c_str()); else return core::fast_atof(Value.c_str()); } virtual bool getBool() const _IRR_OVERRIDE_ { if (IsStringW) return ValueW.equals_ignore_case(L"true"); else return Value.equals_ignore_case("true"); } virtual core::stringc getString() const _IRR_OVERRIDE_ { if (IsStringW) return core::stringc(ValueW.c_str()); else return Value; } virtual core::stringw getStringW() const _IRR_OVERRIDE_ { if (IsStringW) return ValueW; else return core::stringw(Value.c_str()); } virtual void setInt(s32 intValue) _IRR_OVERRIDE_ { if (IsStringW) ValueW = core::stringw(intValue); else Value = core::stringc(intValue); } virtual void setFloat(f32 floatValue) _IRR_OVERRIDE_ { if (IsStringW) { ValueW = core::stringw((double)floatValue); } else { Value = core::stringc((double)floatValue); } }; virtual void setString(const char* text) _IRR_OVERRIDE_ { if (IsStringW) ValueW = core::stringw(text); else Value = text; } virtual void setString(const wchar_t* text) _IRR_OVERRIDE_ { if (IsStringW) ValueW = text; else Value = core::stringc(text); } virtual E_ATTRIBUTE_TYPE getType() const _IRR_OVERRIDE_ { return EAT_STRING; } virtual const wchar_t* getTypeString() const _IRR_OVERRIDE_ { return L"string"; } virtual void getBinary(void* outdata, s32 maxLength) const _IRR_OVERRIDE_ { const s32 dataSize = maxLength; c8* datac8 = (c8*)(outdata); s32 p = 0; const c8* dataString = Value.c_str(); for (s32 i=0; i= '0' && h <='9') return h-'0'; if (h >= 'a' && h <='f') return h-'a' + 10; return 0; } static inline void getHexStrFromByte(c8 byte, c8* out) { s32 b = (byte & 0xf0) >> 4; for (s32 i=0; i<2; ++i) { if (b >=0 && b <= 9) out[i] = b+'0'; if (b >=10 && b <= 15) out[i] = (b-10)+'a'; b = byte & 0x0f; } } }; // Attribute implemented for binary data class CBinaryAttribute : public CStringAttribute { public: CBinaryAttribute(const char* name, void* binaryData, s32 lengthInBytes) : CStringAttribute(name, binaryData, lengthInBytes) { } virtual E_ATTRIBUTE_TYPE getType() const _IRR_OVERRIDE_ { return EAT_BINARY; } virtual const wchar_t* getTypeString() const _IRR_OVERRIDE_ { return L"binary"; } }; // Attribute implemented for texture references class CTextureAttribute : public IAttribute { public: CTextureAttribute(const char* name, video::ITexture* value, video::IVideoDriver* driver, const io::path& filename) : Value(0), Driver(driver), OverrideName(filename) { if (Driver) Driver->grab(); Name = name; setTexture(value); } virtual ~CTextureAttribute() { if (Driver) Driver->drop(); if (Value) Value->drop(); } virtual video::ITexture* getTexture() const _IRR_OVERRIDE_ { return Value; } virtual bool getBool() const _IRR_OVERRIDE_ { return (Value != 0); } virtual core::stringw getStringW() const _IRR_OVERRIDE_ { // (note: don't try to put all this in some ?: operators, or c++ builder will choke) if ( OverrideName.size() ) return core::stringw(OverrideName); if ( Value ) return core::stringw(Value->getName().getPath().c_str()); return core::stringw(); } virtual core::stringc getString() const _IRR_OVERRIDE_ { // since texture names can be stringw we are careful with the types if ( OverrideName.size() ) return core::stringc(OverrideName); if ( Value ) return core::stringc(Value->getName().getPath().c_str()); return core::stringc(); } virtual void setString(const char* text) _IRR_OVERRIDE_ { if (Driver) { if (text && *text) { setTexture(Driver->getTexture(text)); OverrideName=text; } else setTexture(0); } } virtual void setTexture(video::ITexture* texture, const path& filename) _IRR_OVERRIDE_ { OverrideName = filename; setTexture(texture); }; void setTexture(video::ITexture* value) { if ( value == Value ) return; if (Value) Value->drop(); Value = value; if (Value) Value->grab(); } virtual E_ATTRIBUTE_TYPE getType() const _IRR_OVERRIDE_ { return EAT_TEXTURE; } virtual const wchar_t* getTypeString() const _IRR_OVERRIDE_ { return L"texture"; } video::ITexture* Value; video::IVideoDriver* Driver; io::path OverrideName; }; // Attribute implemented for array of stringw class CStringWArrayAttribute : public IAttribute { public: CStringWArrayAttribute(const char* name, const core::array& value) { Name = name; setArray(value); } virtual core::array getArray() const _IRR_OVERRIDE_ { return Value; } virtual void setArray(const core::array& value) _IRR_OVERRIDE_ { Value = value; } virtual E_ATTRIBUTE_TYPE getType() const _IRR_OVERRIDE_ { return EAT_STRINGWARRAY; } virtual const wchar_t* getTypeString() const _IRR_OVERRIDE_ { return L"stringwarray"; } core::array Value; }; // Attribute implemented for user pointers class CUserPointerAttribute : public IAttribute { public: CUserPointerAttribute(const char* name, void* value) { Name = name; Value = value; } virtual s32 getInt() const _IRR_OVERRIDE_ { return *static_cast(Value); } virtual bool getBool() const _IRR_OVERRIDE_ { return (Value != 0); } virtual core::stringw getStringW() const _IRR_OVERRIDE_ { wchar_t buf[32]; swprintf_irr(buf, 32, L"%p", Value); return core::stringw(buf); } virtual void setString(const char* text) _IRR_OVERRIDE_ { size_t val = 0; switch ( sizeof(void*) ) { case 4: { unsigned int tmp; // not using an irrlicht type - sscanf with %x needs always unsigned int sscanf(text, "%x", &tmp); val = (size_t)tmp; } break; case 8: { #ifdef _MSC_VER const unsigned __int64 tmp = _strtoui64(text, NULL, 16); #else const unsigned long long tmp = strtoull(text, NULL, 16); #endif val = (size_t)tmp; } break; } Value = (void *)val; } virtual E_ATTRIBUTE_TYPE getType() const _IRR_OVERRIDE_ { return EAT_USER_POINTER; } virtual void setUserPointer(void* v) _IRR_OVERRIDE_ { Value = v; } virtual void* getUserPointer() const _IRR_OVERRIDE_ { return Value; } virtual const wchar_t* getTypeString() const _IRR_OVERRIDE_ { return L"userPointer"; } void* Value; }; // todo: CGUIFontAttribute } // end namespace io } // end namespace irr