Browse Source

Added Matrix types to Variant. Added ToString() to Matrix types. Added Matrix getters/setters to XMLElement. Added ToMatrix string conversion functions. Added possibility to assign shader parameters from Matrix variants. Fixed missing setting of Color variant shader parameter on Direct3D9.

Lasse Öörni 11 years ago
parent
commit
f7b99ecdee

+ 1 - 0
Source/Engine/Container/Str.h

@@ -32,6 +32,7 @@ namespace Urho3D
 {
 
 static const int CONVERSION_BUFFER_LENGTH = 128;
+static const int MATRIX_CONVERSION_BUFFER_LENGTH = 256;
 
 class WString;
 

+ 103 - 0
Source/Engine/Core/StringUtils.cpp

@@ -371,11 +371,114 @@ Variant ToVectorVariant(const char* source)
     case 4:
         ret.FromString(VAR_VECTOR4, source);
         break;
+        
+    case 9:
+        ret.FromString(VAR_MATRIX3, source);
+        break;
+
+    case 12:
+        ret.FromString(VAR_MATRIX3X4, source);
+        break;
+
+    case 16:
+        ret.FromString(VAR_MATRIX4, source);
+        break;
     }
     
     return ret;
 }
 
+Matrix3 ToMatrix3(const String& source)
+{
+    return ToMatrix3(source.CString());
+}
+
+Matrix3 ToMatrix3(const char* source)
+{
+    Matrix3 ret(Matrix3::ZERO);
+    
+    unsigned elements = CountElements(source, ' ');
+    if (elements < 9)
+        return ret;
+    
+    char* ptr = (char*)source;
+    ret.m00_ = (float)strtod(ptr, &ptr);
+    ret.m01_ = (float)strtod(ptr, &ptr);
+    ret.m02_ = (float)strtod(ptr, &ptr);
+    ret.m10_ = (float)strtod(ptr, &ptr);
+    ret.m11_ = (float)strtod(ptr, &ptr);
+    ret.m12_ = (float)strtod(ptr, &ptr);
+    ret.m20_ = (float)strtod(ptr, &ptr);
+    ret.m21_ = (float)strtod(ptr, &ptr);
+    ret.m22_ = (float)strtod(ptr, &ptr);
+    
+    return ret;
+}
+
+Matrix3x4 ToMatrix3x4(const String& source)
+{
+    return ToMatrix3x4(source.CString());
+}
+
+Matrix3x4 ToMatrix3x4(const char* source)
+{
+    Matrix3x4 ret(Matrix3x4::ZERO);
+    
+    unsigned elements = CountElements(source, ' ');
+    if (elements < 12)
+        return ret;
+    
+    char* ptr = (char*)source;
+    ret.m00_ = (float)strtod(ptr, &ptr);
+    ret.m01_ = (float)strtod(ptr, &ptr);
+    ret.m02_ = (float)strtod(ptr, &ptr);
+    ret.m03_ = (float)strtod(ptr, &ptr);
+    ret.m10_ = (float)strtod(ptr, &ptr);
+    ret.m11_ = (float)strtod(ptr, &ptr);
+    ret.m12_ = (float)strtod(ptr, &ptr);
+    ret.m13_ = (float)strtod(ptr, &ptr);
+    ret.m20_ = (float)strtod(ptr, &ptr);
+    ret.m21_ = (float)strtod(ptr, &ptr);
+    ret.m22_ = (float)strtod(ptr, &ptr);
+    ret.m23_ = (float)strtod(ptr, &ptr);
+    
+    return ret;
+}
+
+Matrix4 ToMatrix4(const String& source)
+{
+    return ToMatrix4(source.CString());
+}
+
+Matrix4 ToMatrix4(const char* source)
+{
+    Matrix4 ret(Matrix4::ZERO);
+    
+    unsigned elements = CountElements(source, ' ');
+    if (elements < 16)
+        return ret;
+    
+    char* ptr = (char*)source;
+    ret.m00_ = (float)strtod(ptr, &ptr);
+    ret.m01_ = (float)strtod(ptr, &ptr);
+    ret.m02_ = (float)strtod(ptr, &ptr);
+    ret.m03_ = (float)strtod(ptr, &ptr);
+    ret.m10_ = (float)strtod(ptr, &ptr);
+    ret.m11_ = (float)strtod(ptr, &ptr);
+    ret.m12_ = (float)strtod(ptr, &ptr);
+    ret.m13_ = (float)strtod(ptr, &ptr);
+    ret.m20_ = (float)strtod(ptr, &ptr);
+    ret.m21_ = (float)strtod(ptr, &ptr);
+    ret.m22_ = (float)strtod(ptr, &ptr);
+    ret.m23_ = (float)strtod(ptr, &ptr);
+    ret.m30_ = (float)strtod(ptr, &ptr);
+    ret.m31_ = (float)strtod(ptr, &ptr);
+    ret.m32_ = (float)strtod(ptr, &ptr);
+    ret.m33_ = (float)strtod(ptr, &ptr);
+    
+    return ret;
+}
+
 String ToString(void* value)
 {
     return ToStringHex((unsigned)(size_t)value);

+ 14 - 2
Source/Engine/Core/StringUtils.h

@@ -75,10 +75,22 @@ URHO3D_API Vector3 ToVector3(const char* source);
 URHO3D_API Vector4 ToVector4(const String& source, bool allowMissingCoords = false);
 /// Parse a Vector4 from a C string.
 URHO3D_API Vector4 ToVector4(const char* source, bool allowMissingCoords = false);
-/// Parse a float or Vector variant from a string.
+/// Parse a float, Vector or Matrix variant from a string.
 URHO3D_API Variant ToVectorVariant(const String& source);
-/// Parse a float or Vector variant from a string.
+/// Parse a float, Vector or Matrix variant from a C string.
 URHO3D_API Variant ToVectorVariant(const char* source);
+/// Parse a Matrix3 from a string.
+URHO3D_API Matrix3 ToMatrix3(const String& source);
+/// Parse a Matrix3 from a C string.
+URHO3D_API Matrix3 ToMatrix3(const char* source);
+/// Parse a Matrix3x4 from a string.
+URHO3D_API Matrix3x4 ToMatrix3x4(const String& source);
+/// Parse a Matrix3x4 from a C string.
+URHO3D_API Matrix3x4 ToMatrix3x4(const char* source);
+/// Parse a Matrix4 from a string.
+URHO3D_API Matrix4 ToMatrix4(const String& source);
+/// Parse a Matrix4 from a C string.
+URHO3D_API Matrix4 ToMatrix4(const char* source);
 /// Convert a pointer to string (returns hexadecimal.)
 URHO3D_API String ToString(void* value);
 /// Convert an unsigned integer to string as hexadecimal.

+ 110 - 2
Source/Engine/Core/Variant.cpp

@@ -56,6 +56,9 @@ static const char* typeNames[] =
     "IntRect",
     "IntVector2",
     "Ptr",
+    "Matrix3",
+    "Matrix3x4",
+    "Matrix4",
     0
 };
 
@@ -93,6 +96,18 @@ Variant& Variant::operator = (const Variant& rhs)
         *(reinterpret_cast<WeakPtr<RefCounted>*>(&value_)) = *(reinterpret_cast<const WeakPtr<RefCounted>*>(&rhs.value_));
         break;
         
+    case VAR_MATRIX3:
+        *(reinterpret_cast<Matrix3*>(value_.ptr_)) = *(reinterpret_cast<const Matrix3*>(rhs.value_.ptr_));
+        break;
+        
+    case VAR_MATRIX3X4:
+        *(reinterpret_cast<Matrix3x4*>(value_.ptr_)) = *(reinterpret_cast<const Matrix3x4*>(rhs.value_.ptr_));
+        break;
+        
+    case VAR_MATRIX4:
+        *(reinterpret_cast<Matrix4*>(value_.ptr_)) = *(reinterpret_cast<const Matrix4*>(rhs.value_.ptr_));
+        break;
+        
     default:
         value_ = rhs.value_;
         break;
@@ -155,6 +170,15 @@ bool Variant::operator == (const Variant& rhs) const
     case VAR_INTVECTOR2:
         return *(reinterpret_cast<const IntVector2*>(&value_)) == *(reinterpret_cast<const IntVector2*>(&rhs.value_));
 
+    case VAR_MATRIX3:
+        return *(reinterpret_cast<const Matrix3*>(value_.ptr_)) == *(reinterpret_cast<const Matrix3*>(rhs.value_.ptr_));
+
+    case VAR_MATRIX3X4:
+        return *(reinterpret_cast<const Matrix3x4*>(value_.ptr_)) == *(reinterpret_cast<const Matrix3x4*>(rhs.value_.ptr_));
+
+    case VAR_MATRIX4:
+        return *(reinterpret_cast<const Matrix4*>(value_.ptr_)) == *(reinterpret_cast<const Matrix4*>(rhs.value_.ptr_));
+
     default:
         return true;
     }
@@ -269,6 +293,18 @@ void Variant::FromString(VariantType type, const char* value)
         *this = (RefCounted*)0;
         break;
         
+    case VAR_MATRIX3:
+        *this = ToMatrix3(value);
+        break;
+        
+    case VAR_MATRIX3X4:
+        *this = ToMatrix3x4(value);
+        break;
+        
+    case VAR_MATRIX4:
+        *this = ToMatrix4(value);
+        break;
+        
     default:
         SetType(VAR_NONE);
     }
@@ -346,6 +382,15 @@ String Variant::ToString() const
         // Reference string serialization requires typehash-to-name mapping from the context. Can not support here
         // Also variant map or vector string serialization is not supported. XML or binary save should be used instead
         return String::EMPTY;
+
+    case VAR_MATRIX3:
+        return (reinterpret_cast<const Matrix3*>(value_.ptr_))->ToString();
+
+    case VAR_MATRIX3X4:
+        return (reinterpret_cast<const Matrix3x4*>(value_.ptr_))->ToString();
+        
+    case VAR_MATRIX4:
+        return (reinterpret_cast<const Matrix4*>(value_.ptr_))->ToString();
     }
 }
 
@@ -416,6 +461,15 @@ bool Variant::IsZero() const
     case VAR_PTR:
         return *reinterpret_cast<const WeakPtr<RefCounted>*>(&value_) == (RefCounted*)0;
         
+    case VAR_MATRIX3:
+        return *reinterpret_cast<const Matrix3*>(value_.ptr_) == Matrix3::IDENTITY;
+        
+    case VAR_MATRIX3X4:
+        return *reinterpret_cast<const Matrix3x4*>(value_.ptr_) == Matrix3x4::IDENTITY;
+        
+    case VAR_MATRIX4:
+        return *reinterpret_cast<const Matrix4*>(value_.ptr_) == Matrix4::IDENTITY;
+        
     default:
         return true;
     }
@@ -456,6 +510,18 @@ void Variant::SetType(VariantType newType)
         (reinterpret_cast<WeakPtr<RefCounted>*>(&value_))->~WeakPtr<RefCounted>();
         break;
         
+    case VAR_MATRIX3:
+        delete reinterpret_cast<Matrix3*>(value_.ptr_);
+        break;
+        
+    case VAR_MATRIX3X4:
+        delete reinterpret_cast<Matrix3x4*>(value_.ptr_);
+        break;
+        
+    case VAR_MATRIX4:
+        delete reinterpret_cast<Matrix4*>(value_.ptr_);
+        break;
+        
     default:
         break;
     }
@@ -492,6 +558,18 @@ void Variant::SetType(VariantType newType)
         new(reinterpret_cast<WeakPtr<RefCounted>*>(&value_)) WeakPtr<RefCounted>();
         break;
         
+    case VAR_MATRIX3:
+        value_.ptr_ = new Matrix3();
+        break;
+        
+    case VAR_MATRIX3X4:
+        value_.ptr_ = new Matrix3x4();
+        break;
+        
+    case VAR_MATRIX4:
+        value_.ptr_ = new Matrix4();
+        break;
+        
     default:
         break;
     }
@@ -577,6 +655,26 @@ template<> void* Variant::Get<void*>() const
     return GetVoidPtr();
 }
 
+template<> RefCounted* Variant::Get<RefCounted*>() const
+{
+    return GetPtr();
+}
+
+template<> const Matrix3& Variant::Get<const Matrix3&>() const
+{
+    return GetMatrix3();
+}
+
+template<> const Matrix3x4& Variant::Get<const Matrix3x4&>() const
+{
+    return GetMatrix3x4();
+}
+
+template<> const Matrix4& Variant::Get<const Matrix4&>() const
+{
+    return GetMatrix4();
+}
+
 template<> ResourceRef Variant::Get<ResourceRef>() const
 {
     return GetResourceRef();
@@ -642,9 +740,19 @@ template<> PODVector<unsigned char> Variant::Get<PODVector<unsigned char> >() co
     return GetBuffer();
 }
 
-template<> RefCounted* Variant::Get<RefCounted*>() const
+template<> Matrix3 Variant::Get<Matrix3>() const
 {
-    return GetPtr();
+    return GetMatrix3();
+}
+
+template<> Matrix3x4 Variant::Get<Matrix3x4>() const
+{
+    return GetMatrix3x4();
+}
+
+template<> Matrix4 Variant::Get<Matrix4>() const
+{
+    return GetMatrix4();
 }
 
 String Variant::GetTypeName(VariantType type)

+ 69 - 2
Source/Engine/Core/Variant.h

@@ -24,11 +24,11 @@
 
 #include "Color.h"
 #include "HashMap.h"
-#include "Quaternion.h"
+#include "Matrix3.h"
+#include "Matrix3x4.h"
 #include "Ptr.h"
 #include "Rect.h"
 #include "StringHash.h"
-#include "Vector4.h"
 
 namespace Urho3D
 {
@@ -55,6 +55,9 @@ enum VariantType
     VAR_INTRECT,
     VAR_INTVECTOR2,
     VAR_PTR,
+    VAR_MATRIX3,
+    VAR_MATRIX3X4,
+    VAR_MATRIX4,
     MAX_VAR_TYPES
 };
 
@@ -333,6 +336,27 @@ public:
         *this = value;
     }
 
+    /// Construct from a Matrix3.
+    Variant(const Matrix3& value) :
+        type_(VAR_NONE)
+    {
+        *this = value;
+    }
+
+    /// Construct from a Matrix3x4.
+    Variant(const Matrix3x4& value) :
+        type_(VAR_NONE)
+    {
+        *this = value;
+    }
+
+    /// Construct from a Matrix4.
+    Variant(const Matrix4& value) :
+        type_(VAR_NONE)
+    {
+        *this = value;
+    }
+    
     /// Construct from type and value.
     Variant(const String& type, const String& value) :
         type_(VAR_NONE)
@@ -559,6 +583,30 @@ public:
         return *this;
     }
     
+    /// Assign from a Matrix3.
+    Variant& operator = (const Matrix3& rhs)
+    {
+        SetType(VAR_MATRIX3);
+        *(reinterpret_cast<Matrix3*>(value_.ptr_)) = rhs;
+        return *this;
+    }
+    
+    /// Assign from a Matrix3x4.
+    Variant& operator = (const Matrix3x4& rhs)
+    {
+        SetType(VAR_MATRIX3X4);
+        *(reinterpret_cast<Matrix3x4*>(value_.ptr_)) = rhs;
+        return *this;
+    }
+    
+    /// Assign from a Matrix4.
+    Variant& operator = (const Matrix4& rhs)
+    {
+        SetType(VAR_MATRIX4);
+        *(reinterpret_cast<Matrix4*>(value_.ptr_)) = rhs;
+        return *this;
+    }
+    
     /// Test for equality with another variant.
     bool operator == (const Variant& rhs) const;
     /// Test for equality with an integer. To return true, both the type and value must match.
@@ -623,6 +671,13 @@ public:
             return false;
     }
     
+    /// Test for equality with a Matrix3. To return true, both the type and value must match.
+    bool operator == (const Matrix3& rhs) const { return type_ == VAR_MATRIX3 ? *(reinterpret_cast<const Matrix3*>(value_.ptr_)) == rhs : false; }
+    /// Test for equality with a Matrix3x4. To return true, both the type and value must match.
+    bool operator == (const Matrix3x4& rhs) const { return type_ == VAR_MATRIX3X4 ? *(reinterpret_cast<const Matrix3x4*>(value_.ptr_)) == rhs : false; }
+    /// Test for equality with a Matrix4. To return true, both the type and value must match.
+    bool operator == (const Matrix4& rhs) const { return type_ == VAR_MATRIX4 ? *(reinterpret_cast<const Matrix4*>(value_.ptr_)) == rhs : false; }
+    
     /// Test for inequality with another variant.
     bool operator != (const Variant& rhs) const { return !(*this == rhs); }
     /// Test for inequality with an integer.
@@ -665,6 +720,12 @@ public:
     bool operator != (const ShortStringHash& rhs) const { return !(*this == rhs); }
     /// Test for inequality with a RefCounted pointer.
     bool operator != (RefCounted* rhs) const { return !(*this == rhs); }
+    /// Test for inequality with a Matrix3.
+    bool operator != (const Matrix3& rhs) const { return !(*this == rhs); }
+    /// Test for inequality with a Matrix3x4.
+    bool operator != (const Matrix3x4& rhs) const { return !(*this == rhs); }
+    /// Test for inequality with a Matrix4.
+    bool operator != (const Matrix4& rhs) const { return !(*this == rhs); }
     
     /// Set from typename and value strings. Pointers will be set to null, and VariantBuffer or VariantMap types are not supported.
     void FromString(const String& type, const String& value);
@@ -729,6 +790,12 @@ public:
     const IntVector2& GetIntVector2() const { return type_ == VAR_INTVECTOR2 ? *reinterpret_cast<const IntVector2*>(&value_) : IntVector2::ZERO; }
     /// Return a RefCounted pointer or null on type mismatch. Will return null if holding a void pointer, as it can not be safely verified that the object is a RefCounted.
     RefCounted* GetPtr() const { return type_ == VAR_PTR ? *reinterpret_cast<const WeakPtr<RefCounted>*>(&value_) : (RefCounted*)0; }
+    /// Return a Matrix3 or identity on type mismatch.
+    const Matrix3& GetMatrix3() const { return type_ == VAR_MATRIX3 ? *(reinterpret_cast<const Matrix3*>(value_.ptr_)) : Matrix3::IDENTITY; }
+    /// Return a Matrix3x4 or identity on type mismatch.
+    const Matrix3x4& GetMatrix3x4() const { return type_ == VAR_MATRIX3X4 ? *(reinterpret_cast<const Matrix3x4*>(value_.ptr_)) : Matrix3x4::IDENTITY; }
+    /// Return a Matrix4 or identity on type mismatch.
+    const Matrix4& GetMatrix4() const { return type_ == VAR_MATRIX4 ? *(reinterpret_cast<const Matrix4*>(value_.ptr_)) : Matrix4::IDENTITY; }
     /// Return value's type.
     VariantType GetType() const { return type_; }
     /// Return value's type name.

+ 16 - 0
Source/Engine/Graphics/Direct3D9/D3D9Graphics.cpp

@@ -1335,6 +1335,22 @@ void Graphics::SetShaderParameter(StringHash param, const Variant& value)
         SetShaderParameter(param, value.GetVector4());
         break;
         
+    case VAR_COLOR:
+        SetShaderParameter(param, value.GetColor());
+        break;
+
+    case VAR_MATRIX3:
+        SetShaderParameter(param, value.GetMatrix3());
+        break;
+        
+    case VAR_MATRIX3X4:
+        SetShaderParameter(param, value.GetMatrix3x4());
+        break;
+        
+    case VAR_MATRIX4:
+        SetShaderParameter(param, value.GetMatrix4());
+        break;
+        
     default:
         // Unsupported parameter type, do nothing
         break;

+ 15 - 3
Source/Engine/Graphics/OpenGL/OGLGraphics.cpp

@@ -1339,15 +1339,15 @@ void Graphics::SetShaderParameter(StringHash param, const Variant& value)
     case VAR_FLOAT:
         SetShaderParameter(param, value.GetFloat());
         break;
-        
+
     case VAR_VECTOR2:
         SetShaderParameter(param, value.GetVector2());
         break;
-        
+
     case VAR_VECTOR3:
         SetShaderParameter(param, value.GetVector3());
         break;
-        
+
     case VAR_VECTOR4:
         SetShaderParameter(param, value.GetVector4());
         break;
@@ -1356,6 +1356,18 @@ void Graphics::SetShaderParameter(StringHash param, const Variant& value)
         SetShaderParameter(param, value.GetColor());
         break;
 
+    case VAR_MATRIX3:
+        SetShaderParameter(param, value.GetMatrix3());
+        break;
+        
+    case VAR_MATRIX3X4:
+        SetShaderParameter(param, value.GetMatrix3x4());
+        break;
+        
+    case VAR_MATRIX4:
+        SetShaderParameter(param, value.GetMatrix4());
+        break;
+
     default:
         // Unsupported parameter type, do nothing
         break;

+ 3 - 0
Source/Engine/LuaScript/pkgs/Core/StringUtils.pkg

@@ -13,6 +13,9 @@ Rect ToRect(const String source);
 Vector2 ToVector2(const String source);
 Vector3 ToVector3(const String source);
 Vector4 ToVector4(const String source, bool allowMissingCoords = false);
+Matrix3 ToMatrix3(const String source);
+Matrix3x4 ToMatrix3x4(const String source);
+Matrix4 ToMatrix4(const String source);
 
 String ToString(void* value);
 String ToStringHex(unsigned value);

+ 71 - 5
Source/Engine/LuaScript/pkgs/Core/Variant.pkg

@@ -21,6 +21,9 @@ enum VariantType
     VAR_INTRECT,
     VAR_INTVECTOR2,
     VAR_PTR,
+    VAR_MATRIX3,
+    VAR_MATRIX3X4,
+    VAR_MATRIX4,
     MAX_VAR_TYPES
 };
 
@@ -31,7 +34,7 @@ struct ResourceRef
     ResourceRef(ShortStringHash type, String name);
     ResourceRef(const ResourceRef& rhs);
     ~ResourceRef();
-    
+
     ShortStringHash type_ @ type;
     String name_ @ name;
 
@@ -43,7 +46,7 @@ struct ResourceRefList
     ResourceRefList();
     ResourceRefList(ShortStringHash type);
     ~ResourceRefList();
-    
+
     ShortStringHash type_ @ type;
 
     bool operator == (const ResourceRefList& rhs) const;
@@ -69,6 +72,9 @@ class Variant
     Variant(const ResourceRefList& value);
     Variant(const IntRect& value);
     Variant(const IntVector2& value);
+    Variant(const Matrix3& value);
+    Variant(const Matrix3x4& value);
+    Variant(const Matrix4& value);
     Variant(const String type, const String value);
     Variant(VariantType type, const String value);
     Variant(VariantType type, const char* value);
@@ -94,6 +100,9 @@ class Variant
     bool operator == (const IntVector2& rhs) const;
     bool operator == (const StringHash& rhs) const;
     bool operator == (const ShortStringHash& rhs) const;
+    bool operator == (const Matrix3& rhs) const;
+    bool operator == (const Matrix3x4& rhs) const;
+    bool operator == (const Matrix4& rhs) const;
 
     tolua_outside void VariantSetInt @ SetInt(int value);
     tolua_outside void VariantSetUint @ SetUint(unsigned value);
@@ -112,7 +121,10 @@ class Variant
     tolua_outside void VariantSetResourceRefList @ SetResourceRefList(const ResourceRefList& value);
     tolua_outside void VariantSetIntRect @ SetIntRect(const IntRect& value);
     tolua_outside void VariantSetIntVector2 @ SetIntVector2(const IntVector2& value);
-    
+    tolua_outside void VariantSetMatrix3 @ SetMatrix3(const Matrix3& value);
+    tolua_outside void VariantSetMatrix3x4 @ SetMatrix3x4(const Matrix3x4& value);
+    tolua_outside void VariantSetMatrix4 @ SetMatrix4(const Matrix4& value);
+
     int GetInt() const;
     int GetUInt() const;
     StringHash GetStringHash();
@@ -130,13 +142,16 @@ class Variant
     const ResourceRefList& GetResourceRefList() const;
     const IntRect& GetIntRect() const;
     const IntVector2& GetIntVector2() const;
+    const Matrix3& GetMatrix3() const;
+    const Matrix3x4& GetMatrix3x4() const;
+    const Matrix4& GetMatrix4() const;
 
     VariantType GetType() const;
     String GetTypeName() const;
     String ToString() const;
     bool IsZero() const;
     bool IsEmpty() const;
-    
+
     tolua_readonly tolua_property__get_set VariantType type;
     tolua_readonly tolua_property__get_set String typeName;
     tolua_readonly tolua_property__is_set bool zero;
@@ -147,7 +162,7 @@ class VariantMap
 {
     VariantMap();
     ~VariantMap();
-    
+
     tolua_outside void VariantMapSetInt @ SetInt(const String key, int value);
     tolua_outside void VariantMapSetUInt @ SetUInt(const String key, unsigned value);
     tolua_outside void VariantMapSetStringHash @ SetStringHash(const String key, const StringHash& value);
@@ -166,6 +181,9 @@ class VariantMap
     tolua_outside void VariantMapSetIntRect @ SetIntRect(const String key, const IntRect value);
     tolua_outside void VariantMapSetIntVector2 @ SetIntVector2(const String key, const IntVector2 value);
     tolua_outside void VariantMapSetPtr @ SetPtr(const String key, void* value);
+    tolua_outside void VariantMapSetMatrix3 @ SetMatrix3(const String key, const Matrix3 value);
+    tolua_outside void VariantMapSetMatrix3x4 @ SetMatrix3x4(const String key, const Matrix3x4 value);
+    tolua_outside void VariantMapSetMatrix4 @ SetMatrix4(const String key, const Matrix4 value);
 
     tolua_outside int VariantMapGetInt @ GetInt(const String key);
     tolua_outside int VariantMapGetUInt @ GetUInt(const String key);
@@ -185,6 +203,9 @@ class VariantMap
     tolua_outside const IntRect& VariantMapGetIntRect @ GetIntRect(const String key);
     tolua_outside const IntVector2& VariantMapGetIntVector2 @ GetIntVector2(const String key);
     tolua_outside const void* VariantMapGetPtr @ GetPtr(const String type, const String key);
+    tolua_outside const Matrix3& VariantMapGetMatrix3 @ GetMatrix3(const String key);
+    tolua_outside const Matrix3x4& VariantMapGetMatrix3x4 @ GetMatrix3x4(const String key);
+    tolua_outside const Matrix4& VariantMapGetMatrix4 @ GetMatrix4(const String key);
 };
 
 ${
@@ -273,6 +294,21 @@ static void VariantSetIntVector2(Variant* variant, const IntVector2& value)
     *variant = value;
 }
 
+static void VariantSetMatrix3(Variant* variant, const Matrix3& value)
+{
+    *variant = value;
+}
+
+static void VariantSetMatrix3x4(Variant* variant, const Matrix3x4& value)
+{
+    *variant = value;
+}
+
+static void VariantSetMatrix4(Variant* variant, const Matrix4& value)
+{
+    *variant = value;
+}
+
 static VectorBuffer VariantGetBuffer(const Variant* variant)
 {
     return VectorBuffer(variant->GetBuffer());
@@ -368,6 +404,21 @@ static void VariantMapSetPtr(VariantMap* vmap, const String& key, void* value)
     (*vmap)[ShortStringHash(key)] = value;
 }
 
+static void VariantMapSetMatrix3(VariantMap* vmap, const String& key, const Matrix3& value)
+{
+    (*vmap)[ShortStringHash(key)] = value;
+}
+
+static void VariantMapSetMatrix3x4(VariantMap* vmap, const String& key, const Matrix3x4& value)
+{
+    (*vmap)[ShortStringHash(key)] = value;
+}
+
+static void VariantMapSetMatrix4(VariantMap* vmap, const String& key, const Matrix4& value)
+{
+    (*vmap)[ShortStringHash(key)] = value;
+}
+
 static const Variant& FindVariant(const VariantMap* vmap, const String& key)
 {
     VariantMap::ConstIterator i = vmap->Find(ShortStringHash(key));
@@ -460,6 +511,21 @@ static const IntVector2& VariantMapGetIntVector2(const VariantMap* vmap, const S
     return FindVariant(vmap, key).GetIntVector2();
 }
 
+static const Matrix3& VariantMapGetMatrix3(const VariantMap* vmap, const String& key)
+{
+    return FindVariant(vmap, key).GetMatrix3();
+}
+
+static const Matrix3x4& VariantMapGetMatrix3x4(const VariantMap* vmap, const String& key)
+{
+    return FindVariant(vmap, key).GetMatrix3x4();
+}
+
+static const Matrix4& VariantMapGetMatrix4(const VariantMap* vmap, const String& key)
+{
+    return FindVariant(vmap, key).GetMatrix4();
+}
+
 #define TOLUA_DISABLE_tolua_CoreLuaAPI_VariantMap_SetPtr00
 static int tolua_CoreLuaAPI_VariantMap_SetPtr00(lua_State* tolua_S)
 {

+ 4 - 2
Source/Engine/LuaScript/pkgs/Math/Matrix3.pkg

@@ -25,7 +25,9 @@ class Matrix3
     Matrix3 Scaled(const Vector3& scale) const;
     bool Equals(const Matrix3& rhs) const;
     Matrix3 Inverse() const;
-    
+
+    String ToString() const;
+
     float m00_ @ m00;
     float m01_ @ m01;
     float m02_ @ m02;
@@ -35,7 +37,7 @@ class Matrix3
     float m20_ @ m20;
     float m21_ @ m21;
     float m22_ @ m22;
-    
+
     static const Matrix3 ZERO;
     static const Matrix3 IDENTITY;
 };

+ 2 - 0
Source/Engine/LuaScript/pkgs/Math/Matrix3x4.pkg

@@ -43,6 +43,8 @@ class Matrix3x4
 
     Matrix3x4 Inverse() const;
     
+    String ToString() const;
+    
     float m00_ @ m00;
     float m01_ @ m01;
     float m02_ @ m02;

+ 2 - 0
Source/Engine/LuaScript/pkgs/Math/Matrix4.pkg

@@ -40,6 +40,8 @@ class Matrix4
     
     Matrix4 Inverse() const;
     
+    String ToString() const;
+    
     float m00_ @ m00;
     float m01_ @ m01;
     float m02_ @ m02;

+ 12 - 6
Source/Engine/LuaScript/pkgs/Resource/XMLElement.pkg

@@ -28,6 +28,9 @@ class XMLElement
     bool SetVector3(const String name, const Vector3& value);
     bool SetVector4(const String name, const Vector4& value);
     bool SetVectorVariant(const String name, const Variant& value);
+    bool SetMatrix3(const String name, const Matrix3& value);
+    bool SetMatrix3x4(const String name, const Matrix3x4& value);
+    bool SetMatrix4(const String name, const Matrix4& value);
 
     bool IsNull() const;
     bool NotNull() const;
@@ -58,21 +61,24 @@ class XMLElement
     Quaternion GetQuaternion(const String name) const;
     Variant GetVariant() const;
     Variant GetVariantValue(VariantType type) const;
-    
+
     ResourceRef GetResourceRef() const;
     ResourceRefList GetResourceRefList() const;
-    
+
     VariantMap GetVariantMap() const;
-    
+
     Vector2 GetVector2(const String name) const;
     Vector3 GetVector3(const String name) const;
     Vector4 GetVector4(const String name) const;
     Vector4 GetVector(const String name) const;
-    
+    Matrix3 GetMatrix3(const String name) const;
+    Matrix3x4 GetMatrix3x4(const String name) const;
+    Matrix4 GetMatrix4(const String name) const;
+
     XMLFile* GetFile() const;
-    
+
     static const XMLElement EMPTY;
-    
+
     tolua_readonly tolua_property__is_set bool null;
     tolua_readonly tolua_property__get_set String name;
     tolua_readonly tolua_property__get_set String value;

+ 11 - 0
Source/Engine/Math/Matrix3.cpp

@@ -23,6 +23,10 @@
 #include "Precompiled.h"
 #include "Matrix3.h"
 
+#include <cstdio>
+
+#include "DebugNew.h"
+
 namespace Urho3D
 {
 
@@ -57,4 +61,11 @@ Matrix3 Matrix3::Inverse() const
     );
 }
 
+String Matrix3::ToString() const
+{
+    char tempBuffer[MATRIX_CONVERSION_BUFFER_LENGTH];
+    sprintf(tempBuffer, "%g %g %g %g %g %g %g %g %g", m00_, m01_, m02_, m10_, m11_, m12_, m20_, m21_, m22_);
+    return String(tempBuffer);
+}
+
 }

+ 2 - 0
Source/Engine/Math/Matrix3.h

@@ -274,6 +274,8 @@ public:
     
     /// Return float data.
     const float* Data() const { return &m00_; }
+    /// Return as string.
+    String ToString() const;
     
     float m00_;
     float m01_;

+ 12 - 0
Source/Engine/Math/Matrix3x4.cpp

@@ -23,6 +23,10 @@
 #include "Precompiled.h"
 #include "Matrix3x4.h"
 
+#include <cstdio>
+
+#include "DebugNew.h"
+
 namespace Urho3D
 {
 
@@ -87,4 +91,12 @@ Matrix3x4 Matrix3x4::Inverse() const
     return ret;
 }
 
+String Matrix3x4::ToString() const
+{
+    char tempBuffer[MATRIX_CONVERSION_BUFFER_LENGTH];
+    sprintf(tempBuffer, "%g %g %g %g %g %g %g %g %g %g %g %g", m00_, m01_, m02_, m03_, m10_, m11_, m12_, m13_, m20_, m21_, m22_,
+        m23_);
+    return String(tempBuffer);
+}
+
 }

+ 2 - 0
Source/Engine/Math/Matrix3x4.h

@@ -465,6 +465,8 @@ public:
     
     /// Return float data.
     const float* Data() const { return &m00_; }
+    /// Return as string.
+    String ToString() const;
     
     float m00_;
     float m01_;

+ 12 - 0
Source/Engine/Math/Matrix4.cpp

@@ -23,6 +23,10 @@
 #include "Precompiled.h"
 #include "Matrix4.h"
 
+#include <cstdio>
+
+#include "DebugNew.h"
+
 namespace Urho3D
 {
 
@@ -105,4 +109,12 @@ Matrix4 Matrix4::Inverse() const
         i30, i31, i32, i33);
 }
 
+String Matrix4::ToString() const
+{
+    char tempBuffer[MATRIX_CONVERSION_BUFFER_LENGTH];
+    sprintf(tempBuffer, "%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g", m00_, m01_, m02_, m03_, m10_, m11_, m12_, m13_, m20_,
+        m21_, m22_, m23_, m30_, m31_, m32_, m33_);
+    return String(tempBuffer);
+}
+
 }

+ 4 - 2
Source/Engine/Math/Matrix4.h

@@ -444,13 +444,15 @@ public:
         return true;
     }
     
-    /// Return decomposition to translation, rotation and scale
+    /// Return decomposition to translation, rotation and scale.
     void Decompose(Vector3& translation, Quaternion& rotation, Vector3& scale) const;
-    /// Return inverse
+    /// Return inverse.
     Matrix4 Inverse() const;
     
     /// Return float data
     const float* Data() const { return &m00_; }
+    /// Return as string.
+    String ToString() const;
     
     float m00_;
     float m01_;

+ 2 - 0
Source/Engine/Math/Vector2.cpp

@@ -25,6 +25,8 @@
 
 #include <cstdio>
 
+#include "DebugNew.h"
+
 namespace Urho3D
 {
 

+ 2 - 0
Source/Engine/Math/Vector3.cpp

@@ -25,6 +25,8 @@
 
 #include <cstdio>
 
+#include "DebugNew.h"
+
 namespace Urho3D
 {
 

+ 2 - 0
Source/Engine/Math/Vector4.cpp

@@ -25,6 +25,8 @@
 
 #include <cstdio>
 
+#include "DebugNew.h"
+
 namespace Urho3D
 {
 

+ 32 - 1
Source/Engine/Resource/XMLElement.cpp

@@ -449,12 +449,28 @@ bool XMLElement::SetVector4(const String& name, const Vector4& value)
 bool XMLElement::SetVectorVariant(const String& name, const Variant& value)
 {
     VariantType type = value.GetType();
-    if (type == VAR_FLOAT || type == VAR_VECTOR2 || type == VAR_VECTOR3 || type == VAR_VECTOR4)
+    if (type == VAR_FLOAT || type == VAR_VECTOR2 || type == VAR_VECTOR3 || type == VAR_VECTOR4 || type == VAR_MATRIX3 ||
+        type == VAR_MATRIX3X4 || type == VAR_MATRIX4)
         return SetAttribute(name, value.ToString());
     else
         return false;
 }
 
+bool XMLElement::SetMatrix3(const String& name, const Matrix3& value)
+{
+    return SetAttribute(name, value.ToString());
+}
+
+bool XMLElement::SetMatrix3x4(const String& name, const Matrix3x4& value)
+{
+    return SetAttribute(name, value.ToString());
+}
+
+bool XMLElement::SetMatrix4(const String& name, const Matrix4& value)
+{
+    return SetAttribute(name, value.ToString());
+}
+
 bool XMLElement::IsNull() const
 {
     return !NotNull();
@@ -829,6 +845,21 @@ Variant XMLElement::GetVectorVariant(const String& name) const
     return ToVectorVariant(GetAttribute(name));
 }
 
+Matrix3 XMLElement::GetMatrix3(const String& name) const
+{
+    return ToMatrix3(GetAttribute(name));
+}
+
+Matrix3x4 XMLElement::GetMatrix3x4(const String& name) const
+{
+    return ToMatrix3x4(GetAttribute(name));
+}
+
+Matrix4 XMLElement::GetMatrix4(const String& name) const
+{
+    return ToMatrix4(GetAttribute(name));
+}
+
 XMLFile* XMLElement::GetFile() const
 {
     return file_;

+ 18 - 6
Source/Engine/Resource/XMLElement.h

@@ -144,9 +144,15 @@ public:
     bool SetVector3(const String& name, const Vector3& value);
     /// Set a Vector4 attribute.
     bool SetVector4(const String& name, const Vector4& value);
-    /// Set a float or Vector attribute stored in a variant.
+    /// Set a float, Vector or Matrix attribute stored in a variant.
     bool SetVectorVariant(const String& name, const Variant& value);
-
+    /// Set a Matrix3 attribute.
+    bool SetMatrix3(const String& name, const Matrix3& value);
+    /// Set a Matrix3x4 attribute.
+    bool SetMatrix3x4(const String& name, const Matrix3x4& value);
+    /// Set a Matrix4 attribute.
+    bool SetMatrix4(const String& name, const Matrix4& value);
+    
     /// Return whether does not refer to an element or an XPath node.
     bool IsNull() const;
     /// Return whether refers to an element or an XPath node.
@@ -229,16 +235,22 @@ public:
     VariantVector GetVariantVector() const;
     /// Return a variant map attribute, or empty if missing.
     VariantMap GetVariantMap() const;
-    /// Return a Vector2 attribute, or default if missing.
+    /// Return a Vector2 attribute, or zero vector if missing.
     Vector2 GetVector2(const String& name) const;
-    /// Return a Vector3 attribute, or default if missing.
+    /// Return a Vector3 attribute, or zero vector if missing.
     Vector3 GetVector3(const String& name) const;
-    /// Return a Vector4 attribute, or default if missing.
+    /// Return a Vector4 attribute, or zero vector if missing.
     Vector4 GetVector4(const String& name) const;
     /// Return any Vector attribute as Vector4. Missing coordinates will be zero.
     Vector4 GetVector(const String& name) const;
-    /// Return a float or Vector attribute as Variant.
+    /// Return a float, Vector or Matrix attribute as Variant.
     Variant GetVectorVariant(const String& name) const;
+    /// Return a Matrix3 attribute, or zero matrix if missing.
+    Matrix3 GetMatrix3(const String& name) const;
+    /// Return a Matrix3x4 attribute, or zero matrix if missing.
+    Matrix3x4 GetMatrix3x4(const String& name) const;
+    /// Return a Matrix4 attribute, or zero matrix if missing.
+    Matrix4 GetMatrix4(const String& name) const;
     /// Return XML file.
     XMLFile* GetFile() const;
     /// Return pugixml xml_node_struct.

+ 32 - 0
Source/Engine/Script/CoreAPI.cpp

@@ -305,6 +305,20 @@ static void ConstructVariantPtr(RefCounted* value, Variant* ptr)
     new(ptr) Variant(value);
 }
 
+static void ConstructVariantMatrix3(const Matrix3& value, Variant* ptr)
+{
+    new(ptr) Variant(value);
+}
+
+static void ConstructVariantMatrix3x4(const Matrix3x4& value, Variant* ptr)
+{
+    new(ptr) Variant(value);
+}
+
+static void ConstructVariantMatrix4(const Matrix4& value, Variant* ptr)
+{
+    new(ptr) Variant(value);
+}
 
 static void ConstructVariantTypeNameValue(const String& type, const String& value, Variant* ptr)
 {
@@ -413,6 +427,9 @@ static void RegisterVariant(asIScriptEngine* engine)
     engine->RegisterEnumValue("VariantType", "VAR_INTRECT", VAR_INTRECT);
     engine->RegisterEnumValue("VariantType", "VAR_INTVECTOR2", VAR_INTVECTOR2);
     engine->RegisterEnumValue("VariantType", "VAR_PTR", VAR_PTR);
+    engine->RegisterEnumValue("VariantType", "VAR_MATRIX3", VAR_MATRIX3);
+    engine->RegisterEnumValue("VariantType", "VAR_MATRIX3X4", VAR_MATRIX3X4);
+    engine->RegisterEnumValue("VariantType", "VAR_MATRIX4", VAR_MATRIX4);
 
     engine->RegisterObjectType("ResourceRef", sizeof(ResourceRef), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_CK);
     engine->RegisterObjectBehaviour("ResourceRef", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ConstructResourceRef), asCALL_CDECL_OBJLAST);
@@ -461,6 +478,9 @@ static void RegisterVariant(asIScriptEngine* engine)
     engine->RegisterObjectBehaviour("Variant", asBEHAVE_CONSTRUCT, "void f(const IntRect&in)", asFUNCTION(ConstructVariantIntRect), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectBehaviour("Variant", asBEHAVE_CONSTRUCT, "void f(const IntVector2&in)", asFUNCTION(ConstructVariantIntVector2), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectBehaviour("Variant", asBEHAVE_CONSTRUCT, "void f(RefCounted@+)", asFUNCTION(ConstructVariantPtr), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectBehaviour("Variant", asBEHAVE_CONSTRUCT, "void f(const Matrix3&in)", asFUNCTION(ConstructVariantMatrix3), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectBehaviour("Variant", asBEHAVE_CONSTRUCT, "void f(const Matrix3x4&in)", asFUNCTION(ConstructVariantMatrix3x4), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectBehaviour("Variant", asBEHAVE_CONSTRUCT, "void f(const Matrix4&in)", asFUNCTION(ConstructVariantMatrix4), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectBehaviour("Variant", asBEHAVE_CONSTRUCT, "void f(const String&in, const String&in)", asFUNCTION(ConstructVariantTypeNameValue), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectBehaviour("Variant", asBEHAVE_CONSTRUCT, "void f(VariantType, const String&in)", asFUNCTION(ConstructVariantTypeValue), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectBehaviour("Variant", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(DestructVariant), asCALL_CDECL_OBJLAST);
@@ -485,6 +505,9 @@ static void RegisterVariant(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Variant", "Variant& opAssign(const IntRect&in)", asMETHODPR(Variant, operator =, (const IntRect&), Variant&), asCALL_THISCALL);
     engine->RegisterObjectMethod("Variant", "Variant& opAssign(const IntVector2&in)", asMETHODPR(Variant, operator =, (const IntVector2&), Variant&), asCALL_THISCALL);
     engine->RegisterObjectMethod("Variant", "Variant& opAssign(RefCounted@+)", asMETHODPR(Variant, operator =, (RefCounted*), Variant&), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Variant", "Variant& opAssign(const Matrix3&in)", asMETHODPR(Variant, operator =, (const Matrix3&), Variant&), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Variant", "Variant& opAssign(const Matrix3x4&in)", asMETHODPR(Variant, operator =, (const Matrix3x4&), Variant&), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Variant", "Variant& opAssign(const Matrix4&in)", asMETHODPR(Variant, operator =, (const Matrix4&), Variant&), asCALL_THISCALL);
     engine->RegisterObjectMethod("Variant", "bool opEquals(const Variant&in) const", asMETHODPR(Variant, operator ==, (const Variant&) const, bool), asCALL_THISCALL);
     engine->RegisterObjectMethod("Variant", "bool opEquals(int) const", asMETHODPR(Variant, operator ==, (int) const, bool), asCALL_THISCALL);
     engine->RegisterObjectMethod("Variant", "bool opEquals(uint) const", asMETHODPR(Variant, operator ==, (unsigned) const, bool), asCALL_THISCALL);
@@ -505,6 +528,9 @@ static void RegisterVariant(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Variant", "bool opEquals(const IntRect&in) const", asMETHODPR(Variant, operator ==, (const IntRect&) const, bool), asCALL_THISCALL);
     engine->RegisterObjectMethod("Variant", "bool opEquals(const IntVector2&in) const", asMETHODPR(Variant, operator ==, (const IntVector2&) const, bool), asCALL_THISCALL);
     engine->RegisterObjectMethod("Variant", "bool opEquals(RefCounted@+) const", asMETHODPR(Variant, operator ==, (RefCounted*) const, bool), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Variant", "bool opEquals(const Matrix3&in) const", asMETHODPR(Variant, operator ==, (const Matrix3&) const, bool), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Variant", "bool opEquals(const Matrix3x4&in) const", asMETHODPR(Variant, operator ==, (const Matrix3x4&) const, bool), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Variant", "bool opEquals(const Matrix4&in) const", asMETHODPR(Variant, operator ==, (const Matrix4&) const, bool), asCALL_THISCALL);
     engine->RegisterObjectMethod("Variant", "int GetInt() const", asMETHOD(Variant, GetInt), asCALL_THISCALL);
     engine->RegisterObjectMethod("Variant", "uint GetUInt() const", asMETHOD(Variant, GetUInt), asCALL_THISCALL);
     engine->RegisterObjectMethod("Variant", "StringHash GetStringHash() const", asMETHOD(Variant, GetStringHash), asCALL_THISCALL);
@@ -524,6 +550,9 @@ static void RegisterVariant(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Variant", "const IntRect& GetIntRect() const", asMETHOD(Variant, GetIntRect), asCALL_THISCALL);
     engine->RegisterObjectMethod("Variant", "const IntVector2& GetIntVector2() const", asMETHOD(Variant, GetIntVector2), asCALL_THISCALL);
     engine->RegisterObjectMethod("Variant", "RefCounted@+ GetPtr() const", asMETHOD(Variant, GetPtr), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Variant", "const Matrix3& GetMatrix3() const", asMETHOD(Variant, GetMatrix3), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Variant", "const Matrix3x4& GetMatrix3x4() const", asMETHOD(Variant, GetMatrix3x4), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Variant", "const Matrix4& GetMatrix4() const", asMETHOD(Variant, GetMatrix4), asCALL_THISCALL);
     engine->RegisterObjectMethod("Variant", "void FromString(const String&in, const String&in)", asMETHODPR(Variant, FromString, (const String&, const String&), void), asCALL_THISCALL);
     engine->RegisterObjectMethod("Variant", "void FromString(VariantType, const String&in)", asMETHODPR(Variant, FromString, (VariantType, const String&), void), asCALL_THISCALL);
     engine->RegisterObjectMethod("Variant", "String ToString() const", asMETHOD(Variant, ToString), asCALL_THISCALL);
@@ -645,6 +674,9 @@ static void RegisterStringUtils(asIScriptEngine* engine)
     engine->RegisterObjectMethod("String", "Vector3 ToVector3() const", asFUNCTIONPR(ToVector3, (const String&), Vector3), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("String", "Vector4 ToVector4(bool allowMissingCoords = false) const", asFUNCTIONPR(ToVector4, (const String&, bool), Vector4), asCALL_CDECL_OBJFIRST);
     engine->RegisterObjectMethod("String", "Variant ToVectorVariant() const", asFUNCTIONPR(ToVectorVariant, (const String&), Variant), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod("String", "Matrix3 ToMatrix3() const", asFUNCTIONPR(ToMatrix3, (const String&), Matrix3), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod("String", "Matrix3x4 ToMatrix3x4() const", asFUNCTIONPR(ToMatrix3x4, (const String&), Matrix3x4), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod("String", "Matrix4 ToMatrix4() const", asFUNCTIONPR(ToMatrix4, (const String&), Matrix4), asCALL_CDECL_OBJLAST);
     engine->RegisterGlobalFunction("String ToStringHex(int)", asFUNCTION(ToStringHex), asCALL_CDECL);
     engine->RegisterGlobalFunction("String Join(String[]&, const String&in glue)", asFUNCTION(StringJoined), asCALL_CDECL);
     engine->RegisterGlobalFunction("bool IsDigit(uint)", asFUNCTION(IsDigit), asCALL_CDECL);

+ 3 - 0
Source/Engine/Script/MathAPI.cpp

@@ -497,6 +497,7 @@ static void RegisterMatrix3(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Matrix3", "Matrix3 Transpose() const", asMETHODPR(Matrix3, Transpose, () const, Matrix3), asCALL_THISCALL);
     engine->RegisterObjectMethod("Matrix3", "Matrix3 Inverse() const", asMETHODPR(Matrix3, Inverse, () const, Matrix3), asCALL_THISCALL);
     engine->RegisterObjectMethod("Matrix3", "bool Equals(const Matrix3&in) const", asMETHOD(Matrix3, Equals), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Matrix3", "String ToString() const", asMETHOD(Matrix3, ToString), asCALL_THISCALL);
     engine->RegisterObjectProperty("Matrix3", "float m00", offsetof(Matrix3, m00_));
     engine->RegisterObjectProperty("Matrix3", "float m01", offsetof(Matrix3, m01_));
     engine->RegisterObjectProperty("Matrix3", "float m02", offsetof(Matrix3, m02_));
@@ -557,6 +558,7 @@ static void RegisterMatrix4(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Matrix4", "void Decompose(Vector3&, Quaternion&, Vector3&) const", asMETHODPR(Matrix4,Decompose, (Vector3 &, Quaternion &, Vector3 &) const, void), asCALL_THISCALL);
     engine->RegisterObjectMethod("Matrix4", "Matrix4 Inverse() const", asMETHODPR(Matrix4, Inverse, () const, Matrix4), asCALL_THISCALL);
     engine->RegisterObjectMethod("Matrix4", "bool Equals(const Matrix4&in) const", asMETHOD(Matrix4, Equals), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Matrix4", "String ToString() const", asMETHOD(Matrix4, ToString), asCALL_THISCALL);
     engine->RegisterObjectProperty("Matrix4", "float m00", offsetof(Matrix4, m00_));
     engine->RegisterObjectProperty("Matrix4", "float m01", offsetof(Matrix4, m01_));
     engine->RegisterObjectProperty("Matrix4", "float m02", offsetof(Matrix4, m02_));
@@ -644,6 +646,7 @@ static void RegisterMatrix3x4(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Matrix3x4", "void Decompose(Vector3&, Quaternion&, Vector3&) const", asMETHODPR(Matrix3x4, Decompose, (Vector3&, Quaternion&, Vector3&) const, void), asCALL_THISCALL);
     engine->RegisterObjectMethod("Matrix3x4", "Matrix3x4 Inverse() const", asMETHODPR(Matrix3x4, Inverse, () const, Matrix3x4), asCALL_THISCALL);
     engine->RegisterObjectMethod("Matrix3x4", "bool Equals(const Matrix3x4&in) const", asMETHOD(Matrix3x4, Equals), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Matrix3x4", "String ToString() const", asMETHOD(Matrix3x4, ToString), asCALL_THISCALL);
     engine->RegisterObjectProperty("Matrix3x4", "float m00", offsetof(Matrix3x4, m00_));
     engine->RegisterObjectProperty("Matrix3x4", "float m01", offsetof(Matrix3x4, m01_));
     engine->RegisterObjectProperty("Matrix3x4", "float m02", offsetof(Matrix3x4, m02_));

+ 6 - 0
Source/Engine/Script/ResourceAPI.cpp

@@ -269,6 +269,9 @@ static void RegisterXMLElement(asIScriptEngine* engine)
     engine->RegisterObjectMethod("XMLElement", "bool SetVector3(const String&in, const Vector3&in)", asMETHOD(XMLElement, SetVector3), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "bool SetVector4(const String&in, const Vector4&in)", asMETHOD(XMLElement, SetVector4), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "bool SetVectorVariant(const String&in, const Variant&in)", asMETHOD(XMLElement, SetVectorVariant), asCALL_THISCALL);
+    engine->RegisterObjectMethod("XMLElement", "bool SetMatrix3(const String&in, const Matrix3&in)", asMETHOD(XMLElement, SetMatrix3), asCALL_THISCALL);
+    engine->RegisterObjectMethod("XMLElement", "bool SetMatrix3x4(const String&in, const Matrix3x4&in)", asMETHOD(XMLElement, SetMatrix3x4), asCALL_THISCALL);
+    engine->RegisterObjectMethod("XMLElement", "bool SetMatrix4(const String&in, const Matrix4&in)", asMETHOD(XMLElement, SetMatrix4), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "bool HasAttribute(const String&in) const", asMETHODPR(XMLElement, HasAttribute, (const String&) const, bool), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "String GetValue() const", asMETHOD(XMLElement, GetValue), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "String GetAttribute(const String&in arg0 = String()) const", asMETHODPR(XMLElement, GetAttribute, (const String&) const, String), asCALL_THISCALL);
@@ -294,6 +297,9 @@ static void RegisterXMLElement(asIScriptEngine* engine)
     engine->RegisterObjectMethod("XMLElement", "Vector3 GetVector3(const String&in) const", asMETHOD(XMLElement, GetVector3), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "Vector4 GetVector4(const String&in) const", asMETHOD(XMLElement, GetVector4), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "Variant GetVectorVariant(const String&in) const", asMETHOD(XMLElement, GetVectorVariant), asCALL_THISCALL);
+    engine->RegisterObjectMethod("XMLElement", "Matrix3 GetMatrix3(const String&in) const", asMETHOD(XMLElement, GetMatrix3), asCALL_THISCALL);
+    engine->RegisterObjectMethod("XMLElement", "Matrix3x4 GetMatrix3x4(const String&in) const", asMETHOD(XMLElement, GetMatrix3x4), asCALL_THISCALL);
+    engine->RegisterObjectMethod("XMLElement", "Matrix4 GetMatrix4(const String&in) const", asMETHOD(XMLElement, GetMatrix4), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "bool set_value(const String&in)", asMETHODPR(XMLElement, SetValue, (const String&), bool), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "String get_value() const", asMETHOD(XMLElement, GetValue), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "String get_name() const", asMETHOD(XMLElement, GetName), asCALL_THISCALL);