Browse Source

IntVector2 bindings, conversions, serialization, etc.
Also two typos "Intvector2" and "Intrect" fixed.

Henrik Heino 9 years ago
parent
commit
2d8c0cf247
31 changed files with 301 additions and 9 deletions
  1. 11 0
      Source/Urho3D/AngelScript/CoreAPI.cpp
  2. 55 0
      Source/Urho3D/AngelScript/MathAPI.cpp
  3. 2 0
      Source/Urho3D/AngelScript/ResourceAPI.cpp
  4. 4 0
      Source/Urho3D/AngelScript/ScriptFile.cpp
  5. 21 0
      Source/Urho3D/Core/StringUtils.cpp
  6. 5 0
      Source/Urho3D/Core/StringUtils.h
  7. 24 0
      Source/Urho3D/Core/Variant.cpp
  8. 37 0
      Source/Urho3D/Core/Variant.h
  9. 10 0
      Source/Urho3D/IO/Deserializer.cpp
  10. 2 0
      Source/Urho3D/IO/Deserializer.h
  11. 8 0
      Source/Urho3D/IO/Serializer.cpp
  12. 3 0
      Source/Urho3D/IO/Serializer.h
  13. 14 2
      Source/Urho3D/LuaScript/LuaScriptInstance.cpp
  14. 5 0
      Source/Urho3D/LuaScript/ToluaUtils.cpp
  15. 1 0
      Source/Urho3D/LuaScript/pkgs/Core/StringUtils.pkg
  16. 2 0
      Source/Urho3D/LuaScript/pkgs/Core/Variant.pkg
  17. 1 0
      Source/Urho3D/LuaScript/pkgs/IO/Deserializer.pkg
  18. 2 0
      Source/Urho3D/LuaScript/pkgs/IO/File.pkg
  19. 2 0
      Source/Urho3D/LuaScript/pkgs/IO/NamedPipe.pkg
  20. 1 0
      Source/Urho3D/LuaScript/pkgs/IO/Serializer.pkg
  21. 2 0
      Source/Urho3D/LuaScript/pkgs/IO/VectorBuffer.pkg
  22. 37 0
      Source/Urho3D/LuaScript/pkgs/Math/Vector3.pkg
  23. 1 0
      Source/Urho3D/LuaScript/pkgs/Network/HttpRequest.pkg
  24. 2 0
      Source/Urho3D/LuaScript/pkgs/Resource/XMLElement.pkg
  25. 10 0
      Source/Urho3D/Resource/PListFile.cpp
  26. 2 0
      Source/Urho3D/Resource/PListFile.h
  27. 10 0
      Source/Urho3D/Resource/XMLElement.cpp
  28. 4 0
      Source/Urho3D/Resource/XMLElement.h
  29. 8 0
      Source/Urho3D/Scene/Serializable.cpp
  30. 12 4
      Source/Urho3D/Scene/ValueAnimation.cpp
  31. 3 3
      bin/Data/Scripts/Editor/AttributeEditor.as

+ 11 - 0
Source/Urho3D/AngelScript/CoreAPI.cpp

@@ -277,6 +277,11 @@ static void ConstructVariantIntVector2(const IntVector2& value, Variant* ptr)
     new(ptr) Variant(value);
 }
 
+static void ConstructVariantIntVector3(const IntVector3& value, Variant* ptr)
+{
+    new(ptr) Variant(value);
+}
+
 static void ConstructVariantPtr(RefCounted* value, Variant* ptr)
 {
     new(ptr) Variant(value);
@@ -455,6 +460,7 @@ static void RegisterVariant(asIScriptEngine* engine)
     engine->RegisterEnumValue("VariantType", "VAR_VARIANTMAP", VAR_VARIANTMAP);
     engine->RegisterEnumValue("VariantType", "VAR_INTRECT", VAR_INTRECT);
     engine->RegisterEnumValue("VariantType", "VAR_INTVECTOR2", VAR_INTVECTOR2);
+    engine->RegisterEnumValue("VariantType", "VAR_INTVECTOR3", VAR_INTVECTOR3);
     engine->RegisterEnumValue("VariantType", "VAR_PTR", VAR_PTR);
     engine->RegisterEnumValue("VariantType", "VAR_MATRIX3", VAR_MATRIX3);
     engine->RegisterEnumValue("VariantType", "VAR_MATRIX3X4", VAR_MATRIX3X4);
@@ -514,6 +520,7 @@ static void RegisterVariant(asIScriptEngine* engine)
     engine->RegisterObjectBehaviour("Variant", asBEHAVE_CONSTRUCT, "void f(const Rect&in)", asFUNCTION(ConstructVariantRect), asCALL_CDECL_OBJLAST);
     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(const IntVector3&in)", asFUNCTION(ConstructVariantIntVector3), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectBehaviour("Variant", asBEHAVE_CONSTRUCT, "void f(RefCounted@+)", asFUNCTION(ConstructVariantPtr), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectBehaviour("Variant", asBEHAVE_CONSTRUCT, "void f(ScriptObject@+)", asFUNCTION(ConstructVariantScriptObject), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectBehaviour("Variant", asBEHAVE_CONSTRUCT, "void f(const Matrix3&in)", asFUNCTION(ConstructVariantMatrix3), asCALL_CDECL_OBJLAST);
@@ -544,6 +551,7 @@ static void RegisterVariant(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Variant", "Variant& opAssign(const Rect&in)", asMETHODPR(Variant, operator =, (const Rect&), Variant&), asCALL_THISCALL);
     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(const IntVector3&in)", asMETHODPR(Variant, operator =, (const IntVector3&), Variant&), asCALL_THISCALL);
     engine->RegisterObjectMethod("Variant", "Variant& opAssign(RefCounted@+)", asMETHODPR(Variant, operator =, (RefCounted*), Variant&), asCALL_THISCALL);
     engine->RegisterObjectMethod("Variant", "Variant& opAssign(ScriptObject@+)", asMETHODPR(Variant, operator =, (void*), Variant&), asCALL_THISCALL);
     engine->RegisterObjectMethod("Variant", "Variant& opAssign(const Matrix3&in)", asMETHODPR(Variant, operator =, (const Matrix3&), Variant&), asCALL_THISCALL);
@@ -570,6 +578,7 @@ static void RegisterVariant(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Variant", "bool opEquals(const Rect&in) const", asMETHODPR(Variant, operator ==, (const Rect&) const, bool), asCALL_THISCALL);
     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(const IntVector3&in) const", asMETHODPR(Variant, operator ==, (const IntVector3&) const, bool), asCALL_THISCALL);
     engine->RegisterObjectMethod("Variant", "bool opEquals(RefCounted@+) const", asMETHODPR(Variant, operator ==, (RefCounted*) const, bool), asCALL_THISCALL);
     engine->RegisterObjectMethod("Variant", "bool opEquals(ScriptObject@+) const", asMETHODPR(Variant, operator ==, (void*) const, bool), asCALL_THISCALL);
     engine->RegisterObjectMethod("Variant", "bool opEquals(const Matrix3&in) const", asMETHODPR(Variant, operator ==, (const Matrix3&) const, bool), asCALL_THISCALL);
@@ -595,6 +604,7 @@ static void RegisterVariant(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Variant", "const Rect& GetRect() const", asMETHOD(Variant, GetRect), asCALL_THISCALL);
     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", "const IntVector3& GetIntVector3() const", asMETHOD(Variant, GetIntVector3), asCALL_THISCALL);
     engine->RegisterObjectMethod("Variant", "RefCounted@+ GetPtr() const", asMETHOD(Variant, GetPtr), asCALL_THISCALL);
     engine->RegisterObjectMethod("Variant", "ScriptObject@+ GetScriptObject() const", asFUNCTION(VariantGetScriptObject), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("Variant", "const Matrix3& GetMatrix3() const", asMETHOD(Variant, GetMatrix3), asCALL_THISCALL);
@@ -723,6 +733,7 @@ static void RegisterStringUtils(asIScriptEngine* engine)
     engine->RegisterObjectMethod("String", "Color ToColor() const", asFUNCTIONPR(ToColor, (const String&), Color), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("String", "IntRect ToIntRect() const", asFUNCTIONPR(ToIntRect, (const String&), IntRect), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("String", "IntVector2 ToIntVector2() const", asFUNCTIONPR(ToIntVector2, (const String&), IntVector2), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod("String", "IntVector3 ToIntVector3() const", asFUNCTIONPR(ToIntVector3, (const String&), IntVector3), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("String", "Quaternion ToQuaternion() const", asFUNCTIONPR(ToQuaternion, (const String&), Quaternion), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("String", "Vector2 ToVector2() const", asFUNCTIONPR(ToVector2, (const String&), Vector2), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("String", "Vector3 ToVector3() const", asFUNCTIONPR(ToVector3, (const String&), Vector3), asCALL_CDECL_OBJLAST);

+ 55 - 0
Source/Urho3D/AngelScript/MathAPI.cpp

@@ -196,6 +196,60 @@ static void RegisterIntVector2(asIScriptEngine* engine)
     engine->RegisterGlobalFunction("IntVector2 VectorMax(const IntVector2&in, const IntVector2&in)", asFUNCTIONPR(VectorMax, (const IntVector2&, const IntVector2&), IntVector2), asCALL_CDECL);
 }
 
+static void ConstructIntVector3(IntVector3* ptr)
+{
+    new(ptr) IntVector3();
+}
+
+static void ConstructIntVector3Copy(const IntVector3& vector, IntVector3* ptr)
+{
+    new(ptr) IntVector3(vector);
+}
+
+static void ConstructIntVector3Init(int x, int y, int z, IntVector3* ptr)
+{
+    new(ptr) IntVector3(x, y, z);
+}
+
+static void ConstructIntVector3ArrayInit(CScriptArray* data, IntVector3* ptr)
+{
+    new(ptr) IntVector3((static_cast<int*>(data->At(0))));
+}
+
+static CScriptArray* IntVector3Data(IntVector3* ptr)
+{
+    return BufferToArray<int>(ptr->Data(), 3, "int[]");
+}
+
+static void RegisterIntVector3(asIScriptEngine* engine)
+{
+    engine->RegisterObjectType("IntVector3", sizeof(IntVector3), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_CAK);
+    engine->RegisterObjectBehaviour("IntVector3", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ConstructIntVector3), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectBehaviour("IntVector3", asBEHAVE_CONSTRUCT, "void f(const IntVector3&in)", asFUNCTION(ConstructIntVector3Copy), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectBehaviour("IntVector3", asBEHAVE_CONSTRUCT, "void f(int, int, int)", asFUNCTION(ConstructIntVector3Init), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectBehaviour("IntVector3", asBEHAVE_CONSTRUCT, "void f(int[]&)", asFUNCTION(ConstructIntVector3ArrayInit), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod("IntVector3", "int[]& get_data() const", asFUNCTION(IntVector3Data), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod("IntVector3", "IntVector3& opAssign(const IntVector3&in)", asMETHOD(IntVector3, operator =), asCALL_THISCALL);
+    engine->RegisterObjectMethod("IntVector3", "IntVector3& opAddAssign(const IntVector3&in)", asMETHOD(IntVector3, operator +=), asCALL_THISCALL);
+    engine->RegisterObjectMethod("IntVector3", "IntVector3& opSubAssign(const IntVector3&in)", asMETHOD(IntVector3, operator -=), asCALL_THISCALL);
+    engine->RegisterObjectMethod("IntVector3", "IntVector3& opMulAssign(int)", asMETHODPR(IntVector3, operator *=, (int), IntVector3&), asCALL_THISCALL);
+    engine->RegisterObjectMethod("IntVector3", "IntVector3& opDivAssign(int)", asMETHODPR(IntVector3, operator /=, (int), IntVector3&), asCALL_THISCALL);
+    engine->RegisterObjectMethod("IntVector3", "bool opEquals(const IntVector3&in) const", asMETHOD(IntVector3, operator ==), asCALL_THISCALL);
+    engine->RegisterObjectMethod("IntVector3", "IntVector3 opNeg() const", asMETHODPR(IntVector3, operator -, () const, IntVector3), asCALL_THISCALL);
+    engine->RegisterObjectMethod("IntVector3", "IntVector3 opAdd(const IntVector3&in) const", asMETHOD(IntVector3, operator +), asCALL_THISCALL);
+    engine->RegisterObjectMethod("IntVector3", "IntVector3 opSub(const IntVector3&in) const", asMETHODPR(IntVector3, operator -, (const IntVector3&) const, IntVector3), asCALL_THISCALL);
+    engine->RegisterObjectMethod("IntVector3", "IntVector3 opMul(int) const", asMETHODPR(IntVector3, operator *, (int) const, IntVector3), asCALL_THISCALL);
+    engine->RegisterObjectMethod("IntVector3", "IntVector3 opDiv(int) const", asMETHODPR(IntVector3, operator /, (int) const, IntVector3), asCALL_THISCALL);
+    engine->RegisterObjectMethod("IntVector3", "String ToString() const", asMETHOD(IntVector3, ToString), asCALL_THISCALL);
+    engine->RegisterObjectMethod("IntVector3", "uint ToHash() const", asMETHOD(IntVector3, ToHash), asCALL_THISCALL);
+    engine->RegisterObjectMethod("IntVector3", "float Length() const", asMETHOD(IntVector3, Length), asCALL_THISCALL);
+    engine->RegisterObjectProperty("IntVector3", "int x", offsetof(IntVector3, x_));
+    engine->RegisterObjectProperty("IntVector3", "int y", offsetof(IntVector3, y_));
+    engine->RegisterObjectProperty("IntVector3", "int z", offsetof(IntVector3, z_));
+    engine->RegisterGlobalFunction("IntVector3 VectorMin(const IntVector3&in, const IntVector3&in)", asFUNCTIONPR(VectorMin, (const IntVector3&, const IntVector3&), IntVector3), asCALL_CDECL);
+    engine->RegisterGlobalFunction("IntVector3 VectorMax(const IntVector3&in, const IntVector3&in)", asFUNCTIONPR(VectorMax, (const IntVector3&, const IntVector3&), IntVector3), asCALL_CDECL);
+}
+
 static void ConstructVector2(Vector2* ptr)
 {
     new(ptr) Vector2();
@@ -1300,6 +1354,7 @@ void RegisterMathAPI(asIScriptEngine* engine)
 {
     RegisterMathFunctions(engine);
     RegisterIntVector2(engine);
+    RegisterIntVector3(engine);
     RegisterIntRect(engine);
     RegisterVector2(engine);
     RegisterVector3(engine);

+ 2 - 0
Source/Urho3D/AngelScript/ResourceAPI.cpp

@@ -475,6 +475,7 @@ static void RegisterXMLElement(asIScriptEngine* engine)
     engine->RegisterObjectMethod("XMLElement", "bool SetUInt(const String&in, uint)", asMETHOD(XMLElement, SetUInt), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "bool SetIntRect(const String&in, const IntRect&in)", asMETHOD(XMLElement, SetIntRect), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "bool SetIntVector2(const String&in, const IntVector2&in)", asMETHOD(XMLElement, SetIntVector2), asCALL_THISCALL);
+    engine->RegisterObjectMethod("XMLElement", "bool SetIntVector3(const String&in, const IntVector3&in)", asMETHOD(XMLElement, SetIntVector3), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "bool SetQuaternion(const String&in, const Quaternion&in)", asMETHOD(XMLElement, SetQuaternion), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "bool SetVariant(const Variant&in)", asMETHOD(XMLElement, SetVariant), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "bool SetResourceRef(const String&in, const ResourceRef&in)", asMETHOD(XMLElement, SetResourceRef), asCALL_THISCALL);
@@ -506,6 +507,7 @@ static void RegisterXMLElement(asIScriptEngine* engine)
     engine->RegisterObjectMethod("XMLElement", "int GetInt(const String&in) const", asMETHOD(XMLElement, GetInt), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "IntRect GetIntRect(const String&in) const", asMETHOD(XMLElement, GetIntRect), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "IntVector2 GetIntVector2(const String&in) const", asMETHOD(XMLElement, GetIntVector2), asCALL_THISCALL);
+    engine->RegisterObjectMethod("XMLElement", "IntVector3 GetIntVector3(const String&in) const", asMETHOD(XMLElement, GetIntVector3), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "Quaternion GetQuaternion(const String&in) const", asMETHOD(XMLElement, GetQuaternion), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "Variant GetVariant() const", asMETHOD(XMLElement, GetVariant), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "ResourceRef GetResourceRef() const", asMETHOD(XMLElement, GetResourceRef), asCALL_THISCALL);

+ 4 - 0
Source/Urho3D/AngelScript/ScriptFile.cpp

@@ -781,6 +781,10 @@ void ScriptFile::SetParameters(asIScriptContext* context, asIScriptFunction* fun
                     context->SetArgObject(i, (void*)&parameters[i].GetIntVector2());
                     break;
 
+                case VAR_INTVECTOR3:
+                    context->SetArgObject(i, (void*)&parameters[i].GetIntVector3());
+                    break;
+
                 case VAR_COLOR:
                     context->SetArgObject(i, (void*)&parameters[i].GetColor());
                     break;

+ 21 - 0
Source/Urho3D/Core/StringUtils.cpp

@@ -227,6 +227,27 @@ IntVector2 ToIntVector2(const char* source)
     return ret;
 }
 
+IntVector3 ToIntVector3(const String& source)
+{
+    return ToIntVector3(source.CString());
+}
+
+IntVector3 ToIntVector3(const char* source)
+{
+    IntVector3 ret(IntVector3::ZERO);
+
+    unsigned elements = CountElements(source, ' ');
+    if (elements < 3)
+        return ret;
+
+    char* ptr = (char*)source;
+    ret.x_ = (int)strtol(ptr, &ptr, 10);
+    ret.y_ = (int)strtol(ptr, &ptr, 10);
+    ret.z_ = (int)strtol(ptr, &ptr, 10);
+
+    return ret;
+}
+
 Rect ToRect(const String& source)
 {
     return ToRect(source.CString());

+ 5 - 0
Source/Urho3D/Core/StringUtils.h

@@ -59,6 +59,10 @@ URHO3D_API IntRect ToIntRect(const char* source);
 URHO3D_API IntVector2 ToIntVector2(const String& source);
 /// Parse an IntVector2 from a C string.
 URHO3D_API IntVector2 ToIntVector2(const char* source);
+/// Parse an IntVector3 from a string.
+URHO3D_API IntVector3 ToIntVector3(const String& source);
+/// Parse an IntVector3 from a C string.
+URHO3D_API IntVector3 ToIntVector3(const char* source);
 /// Parse a Quaternion from a string. If only 3 components specified, convert Euler angles (degrees) to quaternion.
 URHO3D_API Quaternion ToQuaternion(const String& source);
 /// Parse a Quaternion from a C string. If only 3 components specified, convert Euler angles (degrees) to quaternion.
@@ -136,6 +140,7 @@ template <> inline unsigned FromString<unsigned>(const char* source) { return To
 template <> inline Color FromString<Color>(const char* source) { return ToColor(source); }
 template <> inline IntRect FromString<IntRect>(const char* source) { return ToIntRect(source); }
 template <> inline IntVector2 FromString<IntVector2>(const char* source) { return ToIntVector2(source); }
+template <> inline IntVector3 FromString<IntVector3>(const char* source) { return ToIntVector3(source); }
 template <> inline Quaternion FromString<Quaternion>(const char* source) { return ToQuaternion(source); }
 template <> inline Rect FromString<Rect>(const char* source) { return ToRect(source); }
 template <> inline Vector2 FromString<Vector2>(const char* source) { return ToVector2(source); }

+ 24 - 0
Source/Urho3D/Core/Variant.cpp

@@ -65,6 +65,7 @@ static const char* typeNames[] =
     "Double",
     "StringVector",
     "Rect",
+    "IntVector3",
     0
 };
 
@@ -191,6 +192,9 @@ bool Variant::operator ==(const Variant& rhs) const
     case VAR_INTVECTOR2:
         return *(reinterpret_cast<const IntVector2*>(&value_)) == *(reinterpret_cast<const IntVector2*>(&rhs.value_));
 
+    case VAR_INTVECTOR3:
+        return *(reinterpret_cast<const IntVector3*>(&value_)) == *(reinterpret_cast<const IntVector3*>(&rhs.value_));
+
     case VAR_MATRIX3:
         return *(reinterpret_cast<const Matrix3*>(value_.ptr_)) == *(reinterpret_cast<const Matrix3*>(rhs.value_.ptr_));
 
@@ -332,6 +336,10 @@ void Variant::FromString(VariantType type, const char* value)
         *this = ToIntVector2(value);
         break;
 
+    case VAR_INTVECTOR3:
+        *this = ToIntVector3(value);
+        break;
+
     case VAR_PTR:
         // From string to RefCounted pointer not supported, set to null
         *this = (RefCounted*)0;
@@ -434,6 +442,9 @@ String Variant::ToString() const
     case VAR_INTVECTOR2:
         return (reinterpret_cast<const IntVector2*>(&value_))->ToString();
 
+    case VAR_INTVECTOR3:
+        return (reinterpret_cast<const IntVector3*>(&value_))->ToString();
+
     case VAR_MATRIX3:
         return (reinterpret_cast<const Matrix3*>(value_.ptr_))->ToString();
 
@@ -524,6 +535,9 @@ bool Variant::IsZero() const
     case VAR_INTVECTOR2:
         return *reinterpret_cast<const IntVector2*>(&value_) == IntVector2::ZERO;
 
+    case VAR_INTVECTOR3:
+        return *reinterpret_cast<const IntVector3*>(&value_) == IntVector3::ZERO;
+
     case VAR_PTR:
         return *reinterpret_cast<const WeakPtr<RefCounted>*>(&value_) == (RefCounted*)0;
 
@@ -730,6 +744,11 @@ template <> const IntVector2& Variant::Get<const IntVector2&>() const
     return GetIntVector2();
 }
 
+template <> const IntVector3& Variant::Get<const IntVector3&>() const
+{
+    return GetIntVector3();
+}
+
 template <> const PODVector<unsigned char>& Variant::Get<const PODVector<unsigned char>&>() const
 {
     return GetBuffer();
@@ -830,6 +849,11 @@ template <> IntVector2 Variant::Get<IntVector2>() const
     return GetIntVector2();
 }
 
+template <> IntVector3 Variant::Get<IntVector3>() const
+{
+    return GetIntVector3();
+}
+
 template <> PODVector<unsigned char> Variant::Get<PODVector<unsigned char> >() const
 {
     return GetBuffer();

+ 37 - 0
Source/Urho3D/Core/Variant.h

@@ -61,6 +61,7 @@ enum VariantType
     VAR_DOUBLE,
     VAR_STRINGVECTOR,
     VAR_RECT,
+    VAR_INTVECTOR3,
     MAX_VAR_TYPES
 };
 
@@ -374,6 +375,13 @@ public:
         *this = value;
     }
 
+    /// Construct from an IntVector3.
+    Variant(const IntVector3& value) :
+        type_(VAR_NONE)
+    {
+        *this = value;
+    }
+
     /// Construct from a RefCounted pointer. The object will be stored internally in a WeakPtr so that its expiration can be detected safely.
     Variant(RefCounted* value) :
         type_(VAR_NONE)
@@ -639,6 +647,14 @@ public:
         return *this;
     }
 
+    /// Assign from an IntVector3.
+    Variant& operator =(const IntVector3& rhs)
+    {
+        SetType(VAR_INTVECTOR3);
+        *(reinterpret_cast<IntVector3*>(&value_)) = rhs;
+        return *this;
+    }
+
     /// Assign from a RefCounted pointer. The object will be stored internally in a WeakPtr so that its expiration can be detected safely.
     Variant& operator =(RefCounted* rhs)
     {
@@ -789,6 +805,12 @@ public:
         return type_ == VAR_INTVECTOR2 ? *(reinterpret_cast<const IntVector2*>(&value_)) == rhs : false;
     }
 
+    /// Test for equality with an IntVector3. To return true, both the type and value must match.
+    bool operator ==(const IntVector3& rhs) const
+    {
+        return type_ == VAR_INTVECTOR3 ? *(reinterpret_cast<const IntVector3*>(&value_)) == rhs : false;
+    }
+
     /// Test for equality with a StringHash. To return true, both the type and value must match.
     bool operator ==(const StringHash& rhs) const { return type_ == VAR_INT ? (unsigned)value_.int_ == rhs.Value() : false; }
 
@@ -887,6 +909,9 @@ public:
     /// Test for inequality with an IntVector2.
     bool operator !=(const IntVector2& rhs) const { return !(*this == rhs); }
 
+    /// Test for inequality with an IntVector3.
+    bool operator !=(const IntVector3& rhs) const { return !(*this == rhs); }
+
     /// Test for inequality with a StringHash.
     bool operator !=(const StringHash& rhs) const { return !(*this == rhs); }
 
@@ -1054,6 +1079,12 @@ public:
         return type_ == VAR_INTVECTOR2 ? *reinterpret_cast<const IntVector2*>(&value_) : IntVector2::ZERO;
     }
 
+    /// Return an IntVector3 or empty on type mismatch.
+    const IntVector3& GetIntVector3() const
+    {
+        return type_ == VAR_INTVECTOR3 ? *reinterpret_cast<const IntVector3*>(&value_) : IntVector3::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
     {
@@ -1187,6 +1218,8 @@ template <> inline VariantType GetVariantType<IntRect>() { return VAR_INTRECT; }
 
 template <> inline VariantType GetVariantType<IntVector2>() { return VAR_INTVECTOR2; }
 
+template <> inline VariantType GetVariantType<IntVector3>() { return VAR_INTVECTOR3; }
+
 template <> inline VariantType GetVariantType<Matrix3>() { return VAR_MATRIX3; }
 
 template <> inline VariantType GetVariantType<Matrix3x4>() { return VAR_MATRIX3X4; }
@@ -1224,6 +1257,8 @@ template <> URHO3D_API const IntRect& Variant::Get<const IntRect&>() const;
 
 template <> URHO3D_API const IntVector2& Variant::Get<const IntVector2&>() const;
 
+template <> URHO3D_API const IntVector3& Variant::Get<const IntVector3&>() const;
+
 template <> URHO3D_API const PODVector<unsigned char>& Variant::Get<const PODVector<unsigned char>&>() const;
 
 template <> URHO3D_API void* Variant::Get<void*>() const;
@@ -1264,6 +1299,8 @@ template <> URHO3D_API IntRect Variant::Get<IntRect>() const;
 
 template <> URHO3D_API IntVector2 Variant::Get<IntVector2>() const;
 
+template <> URHO3D_API IntVector3 Variant::Get<IntVector3>() const;
+
 template <> URHO3D_API PODVector<unsigned char> Variant::Get<PODVector<unsigned char> >() const;
 
 template <> URHO3D_API Matrix3 Variant::Get<Matrix3>() const;

+ 10 - 0
Source/Urho3D/IO/Deserializer.cpp

@@ -146,6 +146,13 @@ IntVector2 Deserializer::ReadIntVector2()
     return IntVector2(data);
 }
 
+IntVector3 Deserializer::ReadIntVector3()
+{
+    int data[3];
+    Read(data, sizeof data);
+    return IntVector3(data);
+}
+
 Rect Deserializer::ReadRect()
 {
     float data[4];
@@ -356,6 +363,9 @@ Variant Deserializer::ReadVariant(VariantType type)
     case VAR_INTVECTOR2:
         return Variant(ReadIntVector2());
 
+    case VAR_INTVECTOR3:
+        return Variant(ReadIntVector3());
+
     case VAR_MATRIX3:
         return Variant(ReadMatrix3());
 

+ 2 - 0
Source/Urho3D/IO/Deserializer.h

@@ -83,6 +83,8 @@ public:
     IntRect ReadIntRect();
     /// Read an IntVector2.
     IntVector2 ReadIntVector2();
+    /// Read an IntVector3.
+    IntVector3 ReadIntVector3();
     /// Read a Rect.
     Rect ReadRect();
     /// Read a Vector2.

+ 8 - 0
Source/Urho3D/IO/Serializer.cpp

@@ -100,6 +100,11 @@ bool Serializer::WriteIntVector2(const IntVector2& value)
     return Write(value.Data(), sizeof value) == sizeof value;
 }
 
+bool Serializer::WriteIntVector3(const IntVector3& value)
+{
+    return Write(value.Data(), sizeof value) == sizeof value;
+}
+
 bool Serializer::WriteRect(const Rect& value)
 {
     return Write(value.Data(), sizeof value) == sizeof value;
@@ -304,6 +309,9 @@ bool Serializer::WriteVariantData(const Variant& value)
     case VAR_INTVECTOR2:
         return WriteIntVector2(value.GetIntVector2());
 
+    case VAR_INTVECTOR3:
+        return WriteIntVector3(value.GetIntVector3());
+
     case VAR_MATRIX3:
         return WriteMatrix3(value.GetMatrix3());
 

+ 3 - 0
Source/Urho3D/IO/Serializer.h

@@ -33,6 +33,7 @@ namespace Urho3D
 class Color;
 class IntRect;
 class IntVector2;
+class IntVector3;
 class Quaternion;
 class Rect;
 class Vector2;
@@ -75,6 +76,8 @@ public:
     bool WriteIntRect(const IntRect& value);
     /// Write an IntVector2.
     bool WriteIntVector2(const IntVector2& value);
+    /// Write an IntVector3.
+    bool WriteIntVector3(const IntVector3& value);
     /// Write a Rect.
     bool WriteRect(const Rect& value);
     /// Write a Vector2.

+ 14 - 2
Source/Urho3D/LuaScript/LuaScriptInstance.cpp

@@ -190,6 +190,13 @@ void LuaScriptInstance::OnSetAttribute(const AttributeInfo& attr, const Variant&
                 tolua_register_gc(luaState_, lua_gettop(luaState_));
             }
             break;
+        case VAR_INTVECTOR3:
+            {
+                IntVector3* value = new IntVector3(src.GetIntVector3());
+                tolua_pushusertype(luaState_, value, "IntVector3");
+                tolua_register_gc(luaState_, lua_gettop(luaState_));
+            }
+            break;
         default:
             URHO3D_LOGERROR("Unsupported data type");
             lua_settop(luaState_, top);
@@ -267,6 +274,9 @@ void LuaScriptInstance::OnGetAttribute(const AttributeInfo& attr, Variant& dest)
     case VAR_INTVECTOR2:
         dest = *((IntVector2*)tolua_tousertype(luaState_, -1, 0));
         break;
+    case VAR_INTVECTOR3:
+        dest = *((IntVector3*)tolua_tousertype(luaState_, -1, 0));
+        break;
     default:
         URHO3D_LOGERROR("Unsupported data type");
         return;
@@ -582,10 +592,12 @@ void LuaScriptInstance::GetScriptAttributes()
                     info.type_ = VAR_QUATERNION;
                 else if (typeName == "Color")
                     info.type_ = VAR_COLOR;
-                else if (typeName == "Intrect")
+                else if (typeName == "IntRect")
                     info.type_ = VAR_INTRECT;
-                else if (typeName == "Intvector2")
+                else if (typeName == "IntVector2")
                     info.type_ = VAR_INTVECTOR2;
+                else if (typeName == "IntVector3")
+                    info.type_ = VAR_INTVECTOR3;
             }
             break;
         default:

+ 5 - 0
Source/Urho3D/LuaScript/ToluaUtils.cpp

@@ -271,6 +271,10 @@ void ToluaToVariant(lua_State* L, int narg, void* def, Variant& variant)
                     variant = *static_cast<IntVector2*>(value);
                     break;
 
+                case VAR_INTVECTOR3:
+                    variant = *static_cast<IntVector3*>(value);
+                    break;
+
                 case VAR_MATRIX3:
                     variant = *static_cast<Matrix3*>(value);
                     break;
@@ -357,6 +361,7 @@ void ToluaPushVariant(lua_State* L, const Variant* variant, const char* type)
     case VAR_VARIANTMAP:
     case VAR_INTRECT:
     case VAR_INTVECTOR2:
+    case VAR_INTVECTOR3:
         tolua_pushusertype(L, (void*)variant->Get<const VariantValue*>(), variant->GetTypeName().CString());
         break;
 

+ 1 - 0
Source/Urho3D/LuaScript/pkgs/Core/StringUtils.pkg

@@ -8,6 +8,7 @@ unsigned ToUInt(const String source, int base = 10);
 Color ToColor(const String source);
 IntRect ToIntRect(const String source);
 IntVector2 ToIntVector2(const String source);
+IntVector3 ToIntVector3(const String source);
 Quaternion ToQuaternion(const String source);
 Rect ToRect(const String source);
 Vector2 ToVector2(const String source);

+ 2 - 0
Source/Urho3D/LuaScript/pkgs/Core/Variant.pkg

@@ -28,6 +28,7 @@ enum VariantType
     VAR_DOUBLE,
     VAR_STRINGVECTOR,
     VAR_RECT,
+    VAR_INTVECTOR3,
     MAX_VAR_TYPES
 };
 
@@ -98,6 +99,7 @@ class Variant
     const Rect& GetRect() const;
     const IntRect& GetIntRect() const;
     const IntVector2& GetIntVector2() const;
+    const IntVector3& GetIntVector3() const;
     RefCounted* GetPtr(const char* type) const;
     const Matrix3& GetMatrix3() const;
     const Matrix3x4& GetMatrix3x4() const;

+ 1 - 0
Source/Urho3D/LuaScript/pkgs/IO/Deserializer.pkg

@@ -24,6 +24,7 @@ class Deserializer
     double ReadDouble();
     IntRect ReadIntRect();
     IntVector2 ReadIntVector2();
+    IntVector3 ReadIntVector3();
     Rect ReadRect();
     Vector2 ReadVector2();
     Vector3 ReadVector3();

+ 2 - 0
Source/Urho3D/LuaScript/pkgs/IO/File.pkg

@@ -48,6 +48,7 @@ class File : public Object
     double ReadDouble();
     IntRect ReadIntRect();
     IntVector2 ReadIntVector2();
+    IntVector3 ReadIntVector3();
     Rect ReadRect();
     Vector2 ReadVector2();
     Vector3 ReadVector3();
@@ -94,6 +95,7 @@ class File : public Object
     bool WriteDouble(double value);
     bool WriteIntRect(const IntRect& value);
     bool WriteIntVector2(const IntVector2& value);
+    bool WriteIntVector3(const IntVector3& value);
     bool WriteRect(const Rect& value);
     bool WriteVector2(const Vector2& value);
     bool WriteVector3(const Vector3& value);

+ 2 - 0
Source/Urho3D/LuaScript/pkgs/IO/NamedPipe.pkg

@@ -27,6 +27,7 @@ class NamedPipe : public Object
     double ReadDouble();
     IntRect ReadIntRect();
     IntVector2 ReadIntVector2();
+    IntVector3 ReadIntVector3();
     Rect ReadRect();
     Vector2 ReadVector2();
     Vector3 ReadVector3();
@@ -71,6 +72,7 @@ class NamedPipe : public Object
     bool WriteDouble(double value);
     bool WriteIntRect(const IntRect& value);
     bool WriteIntVector2(const IntVector2& value);
+    bool WriteIntVector3(const IntVector3& value);
     bool WriteRect(const Rect& value);
     bool WriteVector2(const Vector2& value);
     bool WriteVector3(const Vector3& value);

+ 1 - 0
Source/Urho3D/LuaScript/pkgs/IO/Serializer.pkg

@@ -18,6 +18,7 @@ class Serializer
     bool WriteDouble(double value);
     bool WriteIntRect(const IntRect& value);
     bool WriteIntVector2(const IntVector2& value);
+    bool WriteIntVector3(const IntVector3& value);
     bool WriteRect(const Rect& value);
     bool WriteVector2(const Vector2& value);
     bool WriteVector3(const Vector3& value);

+ 2 - 0
Source/Urho3D/LuaScript/pkgs/IO/VectorBuffer.pkg

@@ -41,6 +41,7 @@ class VectorBuffer
     double ReadDouble();
     IntRect ReadIntRect();
     IntVector2 ReadIntVector2();
+    IntVector3 ReadIntVector3();
     Rect ReadRect();
     Vector2 ReadVector2();
     Vector3 ReadVector3();
@@ -87,6 +88,7 @@ class VectorBuffer
     bool WriteDouble(double value);
     bool WriteIntRect(const IntRect& value);
     bool WriteIntVector2(const IntVector2& value);
+    bool WriteIntVector3(const IntVector3& value);
     bool WriteRect(const Rect& value);
     bool WriteVector2(const Vector2& value);
     bool WriteVector3(const Vector3& value);

+ 37 - 0
Source/Urho3D/LuaScript/pkgs/Math/Vector3.pkg

@@ -48,10 +48,47 @@ class Vector3
     static const Vector3 ONE;
 };
 
+class IntVector3
+{
+    IntVector3();
+    IntVector3(int x, int y, int z);
+    IntVector3(const IntVector3& rhs);
+    ~IntVector3();
+
+    bool operator ==(const IntVector3& rhs) const;
+    IntVector3 operator + (const IntVector3& rhs) const;
+    IntVector3 operator - () const;
+    IntVector3 operator - (const IntVector3& rhs) const;
+    IntVector3 operator * (int rhs) const;
+    IntVector3 operator / (int rhs) const;
+
+    String ToString() const;
+    unsigned ToHash() const;
+    float Length() const;
+
+    int x_ @ x;
+    int y_ @ y;
+    int z_ @ z;
+
+    static const IntVector3 ZERO;
+    static const IntVector3 LEFT;
+    static const IntVector3 RIGHT;
+    static const IntVector3 UP;
+    static const IntVector3 DOWN;
+    static const IntVector3 FORWARD;
+    static const IntVector3 BACK;
+    static const IntVector3 ONE;
+};
+
 Vector3 VectorLerp(const Vector3& lhs, const Vector3& rhs, const Vector3& t);
 Vector3 VectorMin(const Vector3& lhs, const Vector3& rhs);
 Vector3 VectorMax(const Vector3& lhs, const Vector3& rhs);
 Vector3 VectorFloor(const Vector3& vec);
 Vector3 VectorRound(const Vector3& vec);
 Vector3 VectorCeil(const Vector3& vec);
+IntVector3 VectorFloorToInt(const Vector3& vec);
+IntVector3 VectorRoundToInt(const Vector3& vec);
+IntVector3 VectorCeilToInt(const Vector3& vec);
+IntVector3 VectorMin(const IntVector3& lhs, const IntVector3& rhs);
+IntVector3 VectorMax(const IntVector3& lhs, const IntVector3& rhs);
 float StableRandom(const Vector3& seed);

+ 1 - 0
Source/Urho3D/LuaScript/pkgs/Network/HttpRequest.pkg

@@ -33,6 +33,7 @@ class HttpRequest
     double ReadDouble();
     IntRect ReadIntRect();
     IntVector2 ReadIntVector2();
+    IntVector3 ReadIntVector3();
     Rect ReadRect();
     Vector2 ReadVector2();
     Vector3 ReadVector3();

+ 2 - 0
Source/Urho3D/LuaScript/pkgs/Resource/XMLElement.pkg

@@ -21,6 +21,7 @@ class XMLElement
     bool SetInt(const String name, int value);
     bool SetIntRect(const String name, const IntRect& value);
     bool SetIntVector2(const String name, const IntVector2& value);
+    bool SetIntVector3(const String name, const IntVector3& value);
     bool SetRect(const String name, const Rect& value);
     bool SetQuaternion(const String name, const Quaternion& value);
     bool SetString(const String name, const String value);
@@ -62,6 +63,7 @@ class XMLElement
     int GetInt(const String name) const;
     IntRect GetIntRect(const String name) const;
     IntVector2 GetIntVector2(const String name) const;
+    IntVector3 GetIntVector3(const String name) const;
     Rect GetRect(const String name) const;
     Quaternion GetQuaternion(const String name) const;
     Variant GetVariant() const;

+ 10 - 0
Source/Urho3D/Resource/PListFile.cpp

@@ -229,6 +229,16 @@ IntVector2 PListValue::GetIntVector2() const
     return IntVector2(x, y);
 }
 
+IntVector3 PListValue::GetIntVector3() const
+{
+    if (type_ != PLVT_STRING)
+        return IntVector3::ZERO;
+
+    int x, y, z;
+    sscanf(string_->CString(), "{%d,%d,%d}", &x, &y, &z);
+    return IntVector3(x, y, z);
+}
+
 const PListValueMap& PListValue::GetValueMap() const
 {
     return type_ == PLVT_VALUEMAP ? *valueMap_ : EMPTY_VALUEMAP;

+ 2 - 0
Source/Urho3D/Resource/PListFile.h

@@ -106,6 +106,8 @@ public:
     IntRect GetIntRect() const;
     /// Return IntVector2, for string type.
     IntVector2 GetIntVector2() const;
+    /// Return IntVector3, for string type.
+    IntVector3 GetIntVector3() const;
     /// Return value map.
     const PListValueMap& GetValueMap() const;
     /// Return value vector.

+ 10 - 0
Source/Urho3D/Resource/XMLElement.cpp

@@ -359,6 +359,11 @@ bool XMLElement::SetIntVector2(const String& name, const IntVector2& value)
     return SetAttribute(name, value.ToString());
 }
 
+bool XMLElement::SetIntVector3(const String& name, const IntVector3& value)
+{
+    return SetAttribute(name, value.ToString());
+}
+
 bool XMLElement::SetRect(const String& name, const Rect& value)
 {
     return SetAttribute(name, value.ToString());
@@ -784,6 +789,11 @@ IntVector2 XMLElement::GetIntVector2(const String& name) const
     return ToIntVector2(GetAttribute(name));
 }
 
+IntVector3 XMLElement::GetIntVector3(const String& name) const
+{
+    return ToIntVector3(GetAttribute(name));
+}
+
 Quaternion XMLElement::GetQuaternion(const String& name) const
 {
     return ToQuaternion(GetAttribute(name));

+ 4 - 0
Source/Urho3D/Resource/XMLElement.h

@@ -128,6 +128,8 @@ public:
     bool SetIntRect(const String& name, const IntRect& value);
     /// Set an IntVector2 attribute.
     bool SetIntVector2(const String& name, const IntVector2& value);
+    /// Set an IntVector3 attribute.
+    bool SetIntVector3(const String& name, const IntVector3& value);
     /// Set a Rect attribute.
     bool SetRect(const String& name, const Rect& value);
     /// Set a quaternion attribute.
@@ -231,6 +233,8 @@ public:
     IntRect GetIntRect(const String& name) const;
     /// Return an IntVector2 attribute, or default if missing.
     IntVector2 GetIntVector2(const String& name) const;
+    /// Return an IntVector3 attribute, or default if missing.
+    IntVector3 GetIntVector3(const String& name) const;
     /// Return a Rect attribute, or default if missing.
     Rect GetRect(const String& name) const;
     /// Return a quaternion attribute, or default if missing.

+ 8 - 0
Source/Urho3D/Scene/Serializable.cpp

@@ -151,6 +151,10 @@ void Serializable::OnSetAttribute(const AttributeInfo& attr, const Variant& src)
         *(reinterpret_cast<IntVector2*>(dest)) = src.GetIntVector2();
         break;
 
+    case VAR_INTVECTOR3:
+        *(reinterpret_cast<IntVector3*>(dest)) = src.GetIntVector3();
+        break;
+
     case VAR_DOUBLE:
         *(reinterpret_cast<double*>(dest)) = src.GetDouble();
         break;
@@ -251,6 +255,10 @@ void Serializable::OnGetAttribute(const AttributeInfo& attr, Variant& dest) cons
         dest = *(reinterpret_cast<const IntVector2*>(src));
         break;
 
+    case VAR_INTVECTOR3:
+        dest = *(reinterpret_cast<const IntVector3*>(src));
+        break;
+
     case VAR_DOUBLE:
         dest = *(reinterpret_cast<const double*>(src));
         break;

+ 12 - 4
Source/Urho3D/Scene/ValueAnimation.cpp

@@ -235,10 +235,10 @@ void ValueAnimation::SetValueType(VariantType valueType)
         (valueType_ == VAR_FLOAT) || (valueType_ == VAR_VECTOR2) || (valueType_ == VAR_VECTOR3) || (valueType_ == VAR_VECTOR4) ||
         (valueType_ == VAR_QUATERNION) || (valueType_ == VAR_COLOR);
 
-    if ((valueType_ == VAR_INTRECT) || (valueType_ == VAR_INTVECTOR2))
+    if ((valueType_ == VAR_INTRECT) || (valueType_ == VAR_INTVECTOR2) || (valueType_ == VAR_INTVECTOR3))
     {
         interpolatable_ = true;
-        // Force linear interpolation for IntRect and IntVector2
+        // Force linear interpolation for IntRect, IntVector2 and IntVector3
         if (interpolationMethod_ == IM_SPLINE)
             interpolationMethod_ = IM_LINEAR;
     }
@@ -259,8 +259,8 @@ void ValueAnimation::SetInterpolationMethod(InterpMethod method)
     if (method == interpolationMethod_)
         return;
 
-    // Force linear interpolation for IntRect and IntVector2
-    if (method == IM_SPLINE && (valueType_ == VAR_INTRECT || valueType_ == VAR_INTVECTOR2))
+    // Force linear interpolation for IntRect, IntVector2 and IntVector3
+    if (method == IM_SPLINE && (valueType_ == VAR_INTRECT || valueType_ == VAR_INTVECTOR2 || valueType_ == VAR_INTVECTOR3))
         method = IM_LINEAR;
 
     interpolationMethod_ = method;
@@ -419,6 +419,14 @@ Variant ValueAnimation::LinearInterpolation(unsigned index1, unsigned index2, fl
             return IntVector2((int)(v1.x_ * s + v2.x_ * t), (int)(v1.y_ * s + v2.y_ * t));
         }
 
+    case VAR_INTVECTOR3:
+        {
+            float s = 1.0f - t;
+            const IntVector3& v1 = value1.GetIntVector3();
+            const IntVector3& v2 = value2.GetIntVector3();
+            return IntVector3((int)(v1.x_ * s + v2.x_ * t), (int)(v1.y_ * s + v2.y_ * t), (int)(v1.z_ * s + v2.z_ * t));
+        }
+
     case VAR_DOUBLE:
         return value1.GetDouble() * (1.0f - t) + value2.GetDouble() * t;
 

+ 3 - 3
bin/Data/Scripts/Editor/AttributeEditor.as

@@ -279,7 +279,7 @@ UIElement@ CreateNumAttributeEditor(ListView@ list, Array<Serializable@>@ serial
     uint numCoords = 1;
     if (type == VAR_VECTOR2 || type == VAR_INTVECTOR2)
         numCoords = 2;
-    if (type == VAR_VECTOR3 || type == VAR_QUATERNION)
+    if (type == VAR_VECTOR3 || type == VAR_INTVECTOR3 || type == VAR_QUATERNION)
         numCoords = 3;
     else if (type == VAR_VECTOR4 || type == VAR_COLOR || type == VAR_INTRECT || type == VAR_RECT)
         numCoords = 4;
@@ -435,7 +435,7 @@ UIElement@ CreateAttributeEditor(ListView@ list, Array<Serializable@>@ serializa
         parent = CreateStringAttributeEditor(list, serializables, info, index, subIndex);
     else if (type == VAR_BOOL)
         parent = CreateBoolAttributeEditor(list, serializables, info, index, subIndex);
-    else if ((type >= VAR_FLOAT && type <= VAR_VECTOR4) || type == VAR_QUATERNION || type == VAR_COLOR || type == VAR_INTVECTOR2 || type == VAR_INTRECT || type == VAR_DOUBLE || type == VAR_RECT)
+    else if ((type >= VAR_FLOAT && type <= VAR_VECTOR4) || type == VAR_QUATERNION || type == VAR_COLOR || type == VAR_INTVECTOR2 || type == VAR_INTVECTOR3 || type == VAR_INTRECT || type == VAR_DOUBLE || type == VAR_RECT)
         parent = CreateNumAttributeEditor(list, serializables, info, index, subIndex);
     else if (type == VAR_INT)
         parent = CreateIntAttributeEditor(list, serializables, info, index, subIndex);
@@ -867,7 +867,7 @@ void SanitizeNumericalValue(VariantType type, String& value)
 {
     if ((type >= VAR_FLOAT && type <= VAR_COLOR) || type == VAR_RECT)
         value = String(value.ToFloat());
-    else if (type == VAR_INT || type == VAR_INTRECT || type == VAR_INTVECTOR2)
+    else if (type == VAR_INT || type == VAR_INTRECT || type == VAR_INTVECTOR2 || type == VAR_INTVECTOR3)
         value = String(value.ToInt());
     else if (type == VAR_DOUBLE)
         value = String(value.ToDouble());