Browse Source

Merge branch 'update-api'

Eugene Kozlov 9 years ago
parent
commit
b23a1bd856
51 changed files with 655 additions and 271 deletions
  1. 16 4
      Source/Urho3D/AngelScript/APITemplates.h
  2. 46 8
      Source/Urho3D/AngelScript/MathAPI.cpp
  3. 8 0
      Source/Urho3D/Container/Pair.h
  4. 141 0
      Source/Urho3D/Container/Ptr.h
  5. 46 0
      Source/Urho3D/Container/VectorBase.h
  6. 25 0
      Source/Urho3D/Core/StringUtils.h
  7. 0 4
      Source/Urho3D/Input/Input.cpp
  8. 1 1
      Source/Urho3D/Input/Input.h
  9. 11 0
      Source/Urho3D/LuaScript/pkgs/Math/MathDefs.pkg
  10. 15 0
      Source/Urho3D/LuaScript/pkgs/Math/Vector2.pkg
  11. 9 0
      Source/Urho3D/LuaScript/pkgs/Math/Vector3.pkg
  12. 8 0
      Source/Urho3D/LuaScript/pkgs/Math/Vector4.pkg
  13. 1 0
      Source/Urho3D/LuaScript/pkgs/Resource/Image.pkg
  14. 2 23
      Source/Urho3D/LuaScript/pkgs/Resource/Resource.pkg
  15. 48 35
      Source/Urho3D/Math/MathDefs.h
  16. 43 0
      Source/Urho3D/Math/Vector2.h
  17. 24 0
      Source/Urho3D/Math/Vector3.h
  18. 21 0
      Source/Urho3D/Math/Vector4.h
  19. 4 10
      Source/Urho3D/Navigation/DynamicNavigationMesh.cpp
  20. 3 3
      Source/Urho3D/Navigation/DynamicNavigationMesh.h
  21. 7 13
      Source/Urho3D/Navigation/NavigationMesh.cpp
  22. 2 2
      Source/Urho3D/Navigation/NavigationMesh.h
  23. 0 3
      Source/Urho3D/Network/Network.cpp
  24. 1 1
      Source/Urho3D/Network/Network.h
  25. 13 29
      Source/Urho3D/Physics/CollisionShape.cpp
  26. 5 5
      Source/Urho3D/Physics/CollisionShape.h
  27. 11 13
      Source/Urho3D/Physics/Constraint.cpp
  28. 2 2
      Source/Urho3D/Physics/Constraint.h
  29. 13 26
      Source/Urho3D/Physics/PhysicsWorld.cpp
  30. 5 5
      Source/Urho3D/Physics/PhysicsWorld.h
  31. 6 15
      Source/Urho3D/Physics/RigidBody.cpp
  32. 5 5
      Source/Urho3D/Physics/RigidBody.h
  33. 65 0
      Source/Urho3D/Resource/Image.cpp
  34. 4 0
      Source/Urho3D/Resource/Image.h
  35. 13 0
      Source/Urho3D/Resource/Resource.cpp
  36. 5 0
      Source/Urho3D/Resource/Resource.h
  37. 5 16
      Source/Urho3D/Resource/XMLElement.cpp
  38. 4 4
      Source/Urho3D/Resource/XMLElement.h
  39. 1 4
      Source/Urho3D/Resource/XMLFile.cpp
  40. 2 2
      Source/Urho3D/Resource/XMLFile.h
  41. 0 2
      Source/Urho3D/Scene/Node.cpp
  42. 1 1
      Source/Urho3D/Scene/Node.h
  43. 1 8
      Source/Urho3D/Scene/Serializable.cpp
  44. 3 3
      Source/Urho3D/Scene/Serializable.h
  45. 2 3
      Source/Urho3D/UI/FontFaceBitmap.cpp
  46. 1 6
      Source/Urho3D/Urho2D/AnimatedSprite2D.cpp
  47. 1 1
      Source/Urho3D/Urho2D/AnimatedSprite2D.h
  48. 1 6
      Source/Urho3D/Urho2D/AnimationSet2D.cpp
  49. 2 2
      Source/Urho3D/Urho2D/AnimationSet2D.h
  50. 0 4
      Source/Urho3D/Urho2D/PhysicsWorld2D.cpp
  51. 2 2
      Source/Urho3D/Urho2D/PhysicsWorld2D.h

+ 16 - 4
Source/Urho3D/AngelScript/APITemplates.h

@@ -777,26 +777,36 @@ template <class T> void RegisterNode(asIScriptEngine* engine, const char* classN
     engine->RegisterObjectMethod(className, "VariantMap& get_vars()", asFUNCTION(NodeGetVars), asCALL_CDECL_OBJLAST);
 }
 
-static bool ResourceLoad(File* file, XMLFile* ptr)
+static bool ResourceLoad(File* file, Resource* ptr)
 {
     return file && ptr->Load(*file);
 }
 
-static bool ResourceLoadVectorBuffer(VectorBuffer& buffer, XMLFile* ptr)
+static bool ResourceLoadVectorBuffer(VectorBuffer& buffer, Resource* ptr)
 {
     return ptr->Load(buffer);
 }
 
-static bool ResourceSave(File* file, XMLFile* ptr)
+static bool ResourceLoadByName(const String& fileName, Resource* ptr)
+{
+    return ptr->Load(fileName);
+}
+
+static bool ResourceSave(File* file, Resource* ptr)
 {
     return file && ptr->Save(*file);
 }
 
-static bool ResourceSaveVectorBuffer(VectorBuffer& buffer, XMLFile* ptr)
+static bool ResourceSaveVectorBuffer(VectorBuffer& buffer, Resource* ptr)
 {
     return ptr->Save(buffer);
 }
 
+static bool ResourceSaveByName(const String& fileName, Resource* ptr)
+{
+    return ptr->Save(fileName);
+}
+
 /// Template function for registering a class derived from Resource.
 template <class T> void RegisterResource(asIScriptEngine* engine, const char* className)
 {
@@ -810,8 +820,10 @@ template <class T> void RegisterResource(asIScriptEngine* engine, const char* cl
     }
     engine->RegisterObjectMethod(className, "bool Load(File@+)", asFUNCTION(ResourceLoad), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod(className, "bool Load(VectorBuffer&)", asFUNCTION(ResourceLoadVectorBuffer), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod(className, "bool Load(const String&in)", asFUNCTION(ResourceLoadByName), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod(className, "bool Save(File@+) const", asFUNCTION(ResourceSave), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod(className, "bool Save(VectorBuffer&) const", asFUNCTION(ResourceSaveVectorBuffer), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod(className, "bool Save(const String&in) const", asFUNCTION(ResourceSaveByName), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod(className, "void set_name(const String&in) const", asMETHODPR(T, SetName, (const String&), void), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "const String& get_name() const", asMETHODPR(T, GetName, () const, const String&), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "uint get_memoryUse() const", asMETHODPR(T, GetMemoryUse, () const, unsigned), asCALL_THISCALL);

+ 46 - 8
Source/Urho3D/AngelScript/MathAPI.cpp

@@ -61,21 +61,27 @@ static void RegisterMathFunctions(asIScriptEngine* engine)
     engine->RegisterGlobalFunction("float Acos(float)", asFUNCTION(Acos<float>), asCALL_CDECL);
     engine->RegisterGlobalFunction("float Atan(float)", asFUNCTION(Atan<float>), asCALL_CDECL);
     engine->RegisterGlobalFunction("float Atan2(float, float)", asFUNCTION(Atan2<float>), asCALL_CDECL);
-    engine->RegisterGlobalFunction("float Abs(float)", asFUNCTIONPR(Abs, (float), float), asCALL_CDECL);
+    engine->RegisterGlobalFunction("float Abs(float)", asFUNCTION(Abs<float>), asCALL_CDECL);
     engine->RegisterGlobalFunction("float Sign(float)", asFUNCTION(Sign<float>), asCALL_CDECL);
-    engine->RegisterGlobalFunction("float Sqrt(float)", asFUNCTION(sqrtf), asCALL_CDECL);
-    engine->RegisterGlobalFunction("float Pow(float, float)", asFUNCTION(powf), asCALL_CDECL);
+    engine->RegisterGlobalFunction("float Sqrt(float)", asFUNCTION(Sqrt<float>), asCALL_CDECL);
+    engine->RegisterGlobalFunction("float Pow(float, float)", asFUNCTION(Pow<float>), asCALL_CDECL);
     engine->RegisterGlobalFunction("float Min(float, float)", asFUNCTIONPR(Min, (float, float), float), asCALL_CDECL);
     engine->RegisterGlobalFunction("int Min(int, int)", asFUNCTIONPR(Min, (int, int), int), asCALL_CDECL);
     engine->RegisterGlobalFunction("float Max(float, float)", asFUNCTIONPR(Max, (float, float), float), asCALL_CDECL);
     engine->RegisterGlobalFunction("int Max(int, int)", asFUNCTIONPR(Max, (int, int), int), asCALL_CDECL);
-    engine->RegisterGlobalFunction("float Clamp(float, float, float)", asFUNCTIONPR(Clamp, (float, float, float), float), asCALL_CDECL);
+    engine->RegisterGlobalFunction("float Clamp(float, float, float)", asFUNCTION(Clamp<float>), asCALL_CDECL);
     engine->RegisterGlobalFunction("float SmoothStep(float, float, float)", asFUNCTION(SmoothStep<float>), asCALL_CDECL);
-    engine->RegisterGlobalFunction("int Clamp(int, int, int)", asFUNCTIONPR(Clamp, (int, int, int), int), asCALL_CDECL);
+    engine->RegisterGlobalFunction("int Clamp(int, int, int)", asFUNCTION(Clamp<float>), asCALL_CDECL);
     engine->RegisterGlobalFunction("float Lerp(float, float, float)", asFUNCTIONPR(Lerp, (float, float, float), float), asCALL_CDECL);
-    engine->RegisterGlobalFunction("float Mod(float, float)", asFUNCTION(fmodf), asCALL_CDECL);
-    engine->RegisterGlobalFunction("float Floor(float)", asFUNCTION(floorf), asCALL_CDECL);
-    engine->RegisterGlobalFunction("float Ceil(float)", asFUNCTION(ceilf), asCALL_CDECL);
+    engine->RegisterGlobalFunction("float InverseLerp(float, float, float)", asFUNCTION(InverseLerp<float>), asCALL_CDECL);
+    engine->RegisterGlobalFunction("float Mod(float, float)", asFUNCTION(Mod<float>), asCALL_CDECL);
+    engine->RegisterGlobalFunction("float Fract(float)", asFUNCTION(Fract<float>), asCALL_CDECL);
+    engine->RegisterGlobalFunction("float Floor(float)", asFUNCTION(Floor<float>), asCALL_CDECL);
+    engine->RegisterGlobalFunction("float Round(float)", asFUNCTION(Round<float>), asCALL_CDECL);
+    engine->RegisterGlobalFunction("float Ceil(float)", asFUNCTION(Ceil<float>), asCALL_CDECL);
+    engine->RegisterGlobalFunction("int FloorToInt(float)", asFUNCTION(FloorToInt<float>), asCALL_CDECL);
+    engine->RegisterGlobalFunction("int RoundToInt(float)", asFUNCTION(RoundToInt<float>), asCALL_CDECL);
+    engine->RegisterGlobalFunction("int CeilToInt(float)", asFUNCTION(CeilToInt<float>), asCALL_CDECL);
     engine->RegisterGlobalFunction("bool IsPowerOfTwo(uint)", asFUNCTION(IsPowerOfTwo), asCALL_CDECL);
     engine->RegisterGlobalFunction("uint NextPowerOfTwo(uint)", asFUNCTION(NextPowerOfTwo), asCALL_CDECL);
     engine->RegisterGlobalFunction("uint CountSetBits(uint)", asFUNCTION(CountSetBits), asCALL_CDECL);
@@ -183,6 +189,8 @@ static void RegisterIntVector2(asIScriptEngine* engine)
     engine->RegisterObjectMethod("IntVector2", "String ToString() const", asMETHOD(IntVector2, ToString), asCALL_THISCALL);
     engine->RegisterObjectProperty("IntVector2", "int x", offsetof(IntVector2, x_));
     engine->RegisterObjectProperty("IntVector2", "int y", offsetof(IntVector2, y_));
+    engine->RegisterGlobalFunction("IntVector2 VectorMin(const IntVector2&in, const IntVector2&in)", asFUNCTIONPR(VectorMin, (const IntVector2&, const IntVector2&), IntVector2), asCALL_CDECL);
+    engine->RegisterGlobalFunction("IntVector2 VectorMax(const IntVector2&in, const IntVector2&in)", asFUNCTIONPR(VectorMax, (const IntVector2&, const IntVector2&), IntVector2), asCALL_CDECL);
 }
 
 static void ConstructVector2(Vector2* ptr)
@@ -236,6 +244,7 @@ static void RegisterVector2(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Vector2", "void Normalize()", asMETHOD(Vector2, Normalize), asCALL_THISCALL);
     engine->RegisterObjectMethod("Vector2", "float DotProduct(const Vector2&in) const", asMETHOD(Vector2, DotProduct), asCALL_THISCALL);
     engine->RegisterObjectMethod("Vector2", "float AbsDotProduct(const Vector2&in) const", asMETHOD(Vector2, AbsDotProduct), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Vector2", "float ProjectOntoAxis(const Vector2&in) const", asMETHOD(Vector2, ProjectOntoAxis), asCALL_THISCALL);
     engine->RegisterObjectMethod("Vector2", "float Angle(const Vector2&in) const", asMETHOD(Vector2, Angle), asCALL_THISCALL);
     engine->RegisterObjectMethod("Vector2", "Vector2 Abs() const", asMETHOD(Vector2, Abs), asCALL_THISCALL);
     engine->RegisterObjectMethod("Vector2", "Vector2 Lerp(const Vector2&in, float) const", asMETHOD(Vector2, Lerp), asCALL_THISCALL);
@@ -247,6 +256,18 @@ static void RegisterVector2(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Vector2", "float get_lengthSquared() const", asMETHOD(Vector2, LengthSquared), asCALL_THISCALL);
     engine->RegisterObjectProperty("Vector2", "float x", offsetof(Vector2, x_));
     engine->RegisterObjectProperty("Vector2", "float y", offsetof(Vector2, y_));
+
+    engine->RegisterGlobalFunction("float StableRandom(const Vector2&in)", asFUNCTIONPR(StableRandom, (const Vector2&), float), asCALL_CDECL);
+    engine->RegisterGlobalFunction("float StableRandom(float)", asFUNCTIONPR(StableRandom, (float), float), asCALL_CDECL);
+    engine->RegisterGlobalFunction("Vector2 VectorLerp(const Vector2&in, const Vector2&in, const Vector2&in)", asFUNCTIONPR(VectorLerp, (const Vector2&, const Vector2&, const Vector2&), Vector2), asCALL_CDECL);
+    engine->RegisterGlobalFunction("Vector2 VectorMin(const Vector2&in, const Vector2&in)", asFUNCTIONPR(VectorMin, (const Vector2&, const Vector2&), Vector2), asCALL_CDECL);
+    engine->RegisterGlobalFunction("Vector2 VectorMax(const Vector2&in, const Vector2&in)", asFUNCTIONPR(VectorMax, (const Vector2&, const Vector2&), Vector2), asCALL_CDECL);
+    engine->RegisterGlobalFunction("Vector2 VectorFloor(const Vector2&in)", asFUNCTIONPR(VectorFloor, (const Vector2&), Vector2), asCALL_CDECL);
+    engine->RegisterGlobalFunction("Vector2 VectorRound(const Vector2&in)", asFUNCTIONPR(VectorFloor, (const Vector2&), Vector2), asCALL_CDECL);
+    engine->RegisterGlobalFunction("Vector2 VectorCeil(const Vector2&in)", asFUNCTIONPR(VectorFloor, (const Vector2&), Vector2), asCALL_CDECL);
+    engine->RegisterGlobalFunction("IntVector2 VectorFloorToInt(const Vector2&in)", asFUNCTIONPR(VectorFloorToInt, (const Vector2&), IntVector2), asCALL_CDECL);
+    engine->RegisterGlobalFunction("IntVector2 VectorRoundToInt(const Vector2&in)", asFUNCTIONPR(VectorRoundToInt, (const Vector2&), IntVector2), asCALL_CDECL);
+    engine->RegisterGlobalFunction("IntVector2 VectorCeilToInt(const Vector2&in)", asFUNCTIONPR(VectorCeilToInt, (const Vector2&), IntVector2), asCALL_CDECL);
 }
 
 static void ConstructVector3(Vector3* ptr)
@@ -318,6 +339,7 @@ static void RegisterVector3(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Vector3", "void Normalize()", asMETHOD(Vector3, Normalize), asCALL_THISCALL);
     engine->RegisterObjectMethod("Vector3", "float DotProduct(const Vector3&in) const", asMETHOD(Vector3, DotProduct), asCALL_THISCALL);
     engine->RegisterObjectMethod("Vector3", "float AbsDotProduct(const Vector3&in) const", asMETHOD(Vector3, AbsDotProduct), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Vector3", "float ProjectOntoAxis(const Vector3&in) const", asMETHOD(Vector3, ProjectOntoAxis), asCALL_THISCALL);
     engine->RegisterObjectMethod("Vector3", "Vector3 CrossProduct(const Vector3&in) const", asMETHOD(Vector3, CrossProduct), asCALL_THISCALL);
     engine->RegisterObjectMethod("Vector3", "Vector3 Abs() const", asMETHOD(Vector3, Abs), asCALL_THISCALL);
     engine->RegisterObjectMethod("Vector3", "Vector3 Lerp(const Vector3&in, float) const", asMETHOD(Vector3, Lerp), asCALL_THISCALL);
@@ -331,6 +353,14 @@ static void RegisterVector3(asIScriptEngine* engine)
     engine->RegisterObjectProperty("Vector3", "float x", offsetof(Vector3, x_));
     engine->RegisterObjectProperty("Vector3", "float y", offsetof(Vector3, y_));
     engine->RegisterObjectProperty("Vector3", "float z", offsetof(Vector3, z_));
+
+    engine->RegisterGlobalFunction("float StableRandom(const Vector3&in)", asFUNCTIONPR(StableRandom, (const Vector3&), float), asCALL_CDECL);
+    engine->RegisterGlobalFunction("Vector3 VectorLerp(const Vector3&in, const Vector3&in, const Vector3&in)", asFUNCTIONPR(VectorLerp, (const Vector3&, const Vector3&, const Vector3&), Vector3), asCALL_CDECL);
+    engine->RegisterGlobalFunction("Vector3 VectorMin(const Vector3&in, const Vector3&in)", asFUNCTIONPR(VectorMin, (const Vector3&, const Vector3&), Vector3), asCALL_CDECL);
+    engine->RegisterGlobalFunction("Vector3 VectorMax(const Vector3&in, const Vector3&in)", asFUNCTIONPR(VectorMax, (const Vector3&, const Vector3&), Vector3), asCALL_CDECL);
+    engine->RegisterGlobalFunction("Vector3 VectorFloor(const Vector3&in)", asFUNCTIONPR(VectorFloor, (const Vector3&), Vector3), asCALL_CDECL);
+    engine->RegisterGlobalFunction("Vector3 VectorRound(const Vector3&in)", asFUNCTIONPR(VectorFloor, (const Vector3&), Vector3), asCALL_CDECL);
+    engine->RegisterGlobalFunction("Vector3 VectorCeil(const Vector3&in)", asFUNCTIONPR(VectorFloor, (const Vector3&), Vector3), asCALL_CDECL);
 }
 
 static void ConstructVector4(Vector4* ptr)
@@ -389,6 +419,7 @@ static void RegisterVector4(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Vector4", "Vector4 opDiv(float) const", asMETHODPR(Vector4, operator /, (float) const, Vector4), asCALL_THISCALL);
     engine->RegisterObjectMethod("Vector4", "float DotProduct(const Vector4&in) const", asMETHOD(Vector4, DotProduct), asCALL_THISCALL);
     engine->RegisterObjectMethod("Vector4", "float AbsDotProduct(const Vector4&in) const", asMETHOD(Vector4, AbsDotProduct), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Vector4", "float ProjectOntoAxis(const Vector3&in) const", asMETHOD(Vector4, ProjectOntoAxis), asCALL_THISCALL);
     engine->RegisterObjectMethod("Vector4", "Vector4 Abs() const", asMETHOD(Vector4, Abs), asCALL_THISCALL);
     engine->RegisterObjectMethod("Vector4", "Vector4 Lerp(const Vector4&in, float) const", asMETHOD(Vector4, Lerp), asCALL_THISCALL);
     engine->RegisterObjectMethod("Vector4", "bool Equals(const Vector4&in) const", asMETHOD(Vector4, Equals), asCALL_THISCALL);
@@ -398,6 +429,13 @@ static void RegisterVector4(asIScriptEngine* engine)
     engine->RegisterObjectProperty("Vector4", "float y", offsetof(Vector4, y_));
     engine->RegisterObjectProperty("Vector4", "float z", offsetof(Vector4, z_));
     engine->RegisterObjectProperty("Vector4", "float w", offsetof(Vector4, w_));
+
+    engine->RegisterGlobalFunction("Vector4 VectorLerp(const Vector4&in, const Vector4&in, const Vector4&in)", asFUNCTIONPR(VectorLerp, (const Vector4&, const Vector4&, const Vector4&), Vector4), asCALL_CDECL);
+    engine->RegisterGlobalFunction("Vector4 VectorMin(const Vector4&in, const Vector4&in)", asFUNCTIONPR(VectorMin, (const Vector4&, const Vector4&), Vector4), asCALL_CDECL);
+    engine->RegisterGlobalFunction("Vector4 VectorMax(const Vector4&in, const Vector4&in)", asFUNCTIONPR(VectorMax, (const Vector4&, const Vector4&), Vector4), asCALL_CDECL);
+    engine->RegisterGlobalFunction("Vector4 VectorFloor(const Vector4&in)", asFUNCTIONPR(VectorFloor, (const Vector4&), Vector4), asCALL_CDECL);
+    engine->RegisterGlobalFunction("Vector4 VectorRound(const Vector4&in)", asFUNCTIONPR(VectorFloor, (const Vector4&), Vector4), asCALL_CDECL);
+    engine->RegisterGlobalFunction("Vector4 VectorCeil(const Vector4&in)", asFUNCTIONPR(VectorFloor, (const Vector4&), Vector4), asCALL_CDECL);
 }
 
 static void ConstructQuaternion(Quaternion* ptr)

+ 8 - 0
Source/Urho3D/Container/Pair.h

@@ -84,4 +84,12 @@ template <class T, class U> Pair<T, U> MakePair(const T& first, const U& second)
     return Pair<T, U>(first, second);
 }
 
+template <class T> T begin(Urho3D::Pair<T, T>& range) { return range.first_; }
+
+template <class T> T end(Urho3D::Pair<T, T>& range) { return range.second_; }
+
+template <class T> T begin(const Urho3D::Pair<T, T>& range) { return range.first_; }
+
+template <class T> T end(const Urho3D::Pair<T, T>& range) { return range.second_; }
+
 }

+ 141 - 0
Source/Urho3D/Container/Ptr.h

@@ -27,6 +27,10 @@
 #include <cassert>
 #include <cstddef>
 
+#if URHO3D_CXX11
+#include <utility>
+#endif
+
 namespace Urho3D
 {
 
@@ -516,4 +520,141 @@ template <class T, class U> WeakPtr<T> DynamicCast(const WeakPtr<U>& ptr)
     return ret;
 }
 
+/// Delete object of type T. T must be complete. See boost::checked_delete.
+template<class T> inline void CheckedDelete(T* x)
+{
+    // intentionally complex - simplification causes regressions
+    typedef char type_must_be_complete[sizeof(T) ? 1 : -1];
+    (void) sizeof(type_must_be_complete);
+    delete x;
+}
+
+/// Unique pointer template class.
+template <class T> class UniquePtr
+{
+    // Make non-copyable
+    UniquePtr(const UniquePtr&);
+    UniquePtr& operator=(const UniquePtr&);
+
+public:
+    /// Construct empty.
+    UniquePtr() : ptr_(0) { }
+
+    /// Construct from pointer.
+    explicit UniquePtr(T* ptr) : ptr_(ptr) { }
+
+    /// Assign from pointer.
+    UniquePtr& operator = (T* ptr)
+    {
+        Reset(ptr);
+        return *this;
+    }
+
+#if URHO3D_CXX11
+    /// Construct empty.
+    UniquePtr(std::nullptr_t) { }
+
+    /// Move-construct from UniquePtr.
+    UniquePtr(UniquePtr && up) : ptr_(up.Detach()) { }
+
+    /// Move-assign from UniquePtr
+    UniquePtr& operator = (UniquePtr && up)
+    {
+        Reset(up.Detach());
+        return *this;
+    }
+#endif
+
+    /// Point to the object.
+    T* operator ->() const
+    {
+        assert(ptr_);
+        return ptr_;
+    }
+
+    /// Dereference the object.
+    T& operator *() const
+    {
+        assert(ptr_);
+        return *ptr_;
+    }
+
+    /// Test for less than with another unique pointer.
+    template <class U>
+    bool operator <(const UniquePtr<U>& rhs) const { return ptr_ < rhs.ptr_; }
+
+    /// Test for equality with another unique pointer.
+    template <class U>
+    bool operator ==(const UniquePtr<U>& rhs) const { return ptr_ == rhs.ptr_; }
+
+    /// Test for inequality with another unique pointer.
+    template <class U>
+    bool operator !=(const UniquePtr<U>& rhs) const { return ptr_ != rhs.ptr_; }
+
+    /// Cast pointer to bool.
+    operator bool() const { return !!ptr_; }
+
+    /// Swap with another UniquePtr.
+    void Swap(UniquePtr& up) { Swap(ptr_, up.ptr_); }
+
+    /// Detach pointer from UniquePtr without destroying.
+    T* Detach()
+    {
+        T* ptr = ptr_;
+        ptr_ = 0;
+        return ptr;
+    }
+
+    /// Check if the pointer is null.
+    bool Null() const { return ptr_ == 0; }
+
+    /// Check if the pointer is not null.
+    bool NotNull() const { return ptr_ != 0; }
+
+    /// Return the raw pointer.
+    T* Get() const { return ptr_; }
+
+    /// Reset.
+    void Reset(T* ptr = 0)
+    {
+        CheckedDelete(ptr_);
+        ptr_ = ptr;
+    }
+
+    /// Return hash value for HashSet & HashMap.
+    unsigned ToHash() const { return (unsigned)((size_t)ptr_ / sizeof(T)); }
+
+    /// Destruct.
+    ~UniquePtr()
+    {
+        Reset();
+    }
+
+private:
+    T* ptr_;
+
+};
+
+/// Swap two UniquePtr-s.
+template <class T> void Swap(UniquePtr<T>& first, UniquePtr<T>& second)
+{
+    first.Swap(second);
+}
+
+#if URHO3D_CXX11
+
+/// Construct UniquePtr.
+template <class T, class ... Args> UniquePtr<T> MakeUnique(Args && ... args)
+{
+    return UniquePtr<T>(new T(std::forward<Args>(args)...));
+}
+
+/// Construct SharedPtr.
+template <class T, class ... Args> SharedPtr<T> MakeShared(Args && ... args)
+{
+    return SharedPtr<T>(new T(std::forward<Args>(args)...));
+}
+
+#endif
+
 }

+ 46 - 0
Source/Urho3D/Container/VectorBase.h

@@ -238,6 +238,52 @@ template <class T> struct RandomAccessConstIterator
     T* ptr_;
 };
 
+/// Returns an iterator pointing to the first element in the range [first, last) that is not less than value.
+template <class TRandomAccessIterator, class T>
+TRandomAccessIterator LowerBound(TRandomAccessIterator first, TRandomAccessIterator last, const T& value)
+{
+    unsigned count = last - first;
+
+    while (count > 0)
+    {
+        const unsigned step = count / 2;
+        const TRandomAccessIterator it = first + step;
+        if (*it < value)
+        {
+            first = it + 1;
+            count -= step + 1;
+        }
+        else
+        {
+            count = step;
+        }
+    }
+    return first;
+}
+
+/// Returns an iterator pointing to the first element in the range [first, last) that is greater than value.
+template <class TRandomAccessIterator, class T>
+TRandomAccessIterator UpperBound(TRandomAccessIterator first, TRandomAccessIterator last, const T& value)
+{
+    unsigned count = last - first;
+
+    while (count > 0)
+    {
+        const unsigned step = count / 2;
+        const TRandomAccessIterator it = first + step;
+        if (!(value < *it))
+        {
+            first = it + 1;
+            count -= step + 1;
+        }
+        else
+        {
+            count = step;
+        };
+    }
+    return first;
+}
+
 /// %Vector base class.
 /** Note that to prevent extra memory use due to vtable pointer, %VectorBase intentionally does not declare a virtual destructor
     and therefore %VectorBase pointers should never be used.

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

@@ -123,5 +123,30 @@ URHO3D_API unsigned ToUpper(unsigned ch);
 URHO3D_API unsigned ToLower(unsigned ch);
 /// Convert a memory size into a formatted size string, of the style "1.5 Mb".
 URHO3D_API String GetFileSizeString(unsigned long long memorySize);
+/// Parse type from a C string.
+template <class T> T FromString(const char* source);
+
+template <> inline const char* FromString<const char*>(const char* source) { return source; }
+template <> inline String FromString<String>(const char* source) { return source; }
+template <> inline bool FromString<bool>(const char* source) { return ToBool(source); }
+template <> inline float FromString<float>(const char* source) { return ToFloat(source); }
+template <> inline double FromString<double>(const char* source) { return ToDouble(source); }
+template <> inline int FromString<int>(const char* source) { return ToInt(source); }
+template <> inline unsigned FromString<unsigned>(const char* source) { return ToUInt(source); }
+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 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); }
+template <> inline Vector3 FromString<Vector3>(const char* source) { return ToVector3(source); }
+template <> inline Vector4 FromString<Vector4>(const char* source) { return ToVector4(source); }
+template <> inline Variant FromString<Variant>(const char* source) { return ToVectorVariant(source); }
+template <> inline Matrix3 FromString<Matrix3>(const char* source) { return ToMatrix3(source); }
+template <> inline Matrix3x4 FromString<Matrix3x4>(const char* source) { return ToMatrix3x4(source); }
+template <> inline Matrix4 FromString<Matrix4>(const char* source) { return ToMatrix4(source); }
+
+/// Parse type from a string.
+template <class T> T FromString(const String& source) { return FromString<T>(source.CString()); }
 
 }

+ 0 - 4
Source/Urho3D/Input/Input.cpp

@@ -364,10 +364,6 @@ Input::Input(Context* context) :
 
 Input::~Input()
 {
-#ifdef __EMSCRIPTEN__
-    delete emscriptenInput_;
-    emscriptenInput_ = 0;
-#endif
 }
 
 void Input::Update()

+ 1 - 1
Source/Urho3D/Input/Input.h

@@ -428,7 +428,7 @@ private:
 
 #ifdef __EMSCRIPTEN__
     /// Emscripten Input glue instance.
-    EmscriptenInput* emscriptenInput_;
+    UniquePtr<EmscriptenInput> emscriptenInput_;
     /// Flag used to detect mouse jump when exiting pointer-lock.
     bool emscriptenExitingPointerLock_;
     /// Flag used to detect mouse jump on initial mouse click when entering pointer-lock.

+ 11 - 0
Source/Urho3D/LuaScript/pkgs/Math/MathDefs.pkg

@@ -27,6 +27,7 @@ enum Intersection
 bool Equals(float lhs, float rhs);
 bool IsNaN(float value);
 float Lerp(float lhs, float rhs, float t);
+float InverseLerp(float lhs, float rhs, float x);
 float Min(float lhs, float rhs);
 float Max(float lhs, float rhs);
 float Abs(float value);
@@ -42,6 +43,16 @@ float Asin(float x);
 float Acos(float x);
 float Atan(float x);
 float Atan2(float y, float x);
+float Sqrt(float x);
+float Pow(float x, float y);
+float Mod(float x, float y);
+float Fract(float x);
+float Floor(float x);
+float Round(float x);
+float Ceil(float x);
+int FloorToInt(float x);
+int RoundToInt(float x);
+int CeilToInt(float x);
 
 int Min @ MinInt(int lhs, int rhs);
 int Max @ MaxInt(int lhs, int rhs);

+ 15 - 0
Source/Urho3D/LuaScript/pkgs/Math/Vector2.pkg

@@ -22,6 +22,7 @@ class Vector2
     float LengthSquared() const;
     float DotProduct(const Vector2& rhs) const;
     float AbsDotProduct(const Vector2& rhs) const;
+    float ProjectOntoAxis(const Vector2& axis) const;
     float Angle(const Vector2& rhs) const;
     Vector2 Abs() const;
     Vector2 Lerp(const Vector2& rhs, float t) const;
@@ -64,3 +65,17 @@ class IntVector2
 
     static const IntVector2 ZERO;
 };
+
+Vector2 VectorLerp(const Vector2& lhs, const Vector2& rhs, const Vector2& t);
+Vector2 VectorMin(const Vector2& lhs, const Vector2& rhs);
+Vector2 VectorMax(const Vector2& lhs, const Vector2& rhs);
+Vector2 VectorFloor(const Vector2& vec);
+Vector2 VectorRound(const Vector2& vec);
+Vector2 VectorCeil(const Vector2& vec);
+IntVector2 VectorFloorToInt(const Vector2& vec);
+IntVector2 VectorRoundToInt(const Vector2& vec);
+IntVector2 VectorCeilToInt(const Vector2& vec);
+IntVector2 VectorMin(const IntVector2& lhs, const IntVector2& rhs);
+IntVector2 VectorMax(const IntVector2& lhs, const IntVector2& rhs);
+float StableRandom(const Vector2& seed);
+float StableRandom(float seed);

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

@@ -23,6 +23,7 @@ class Vector3
     float LengthSquared() const;
     float DotProduct(const Vector3& rhs) const;
     float AbsDotProduct(const Vector3& rhs) const;
+    float ProjectOntoAxis(const Vector3& axis) const;
     Vector3 CrossProduct(const Vector3& rhs) const;
     Vector3 Abs() const;
     Vector3 Lerp(const Vector3& rhs, float t) const;
@@ -46,3 +47,11 @@ class Vector3
     static const Vector3 BACK;
     static const Vector3 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);
+float StableRandom(const Vector3& seed);

+ 8 - 0
Source/Urho3D/LuaScript/pkgs/Math/Vector4.pkg

@@ -20,6 +20,7 @@ class Vector4
 
     float DotProduct(const Vector4& rhs) const;
     float AbsDotProduct(const Vector4& rhs) const;
+    float ProjectOntoAxis(const Vector3& axis) const;
     Vector4 Abs() const;
     Vector4 Lerp(const Vector4& rhs, float t) const;
     bool Equals(const Vector4& rhs) const;
@@ -35,3 +36,10 @@ class Vector4
     static const Vector4 ZERO;
     static const Vector4 ONE;
 };
+
+Vector4 VectorLerp(const Vector4& lhs, const Vector4& rhs, const Vector4& t);
+Vector4 VectorMin(const Vector4& lhs, const Vector4& rhs);
+Vector4 VectorMax(const Vector4& lhs, const Vector4& rhs);
+Vector4 VectorFloor(const Vector4& vec);
+Vector4 VectorRound(const Vector4& vec);
+Vector4 VectorCeil(const Vector4& vec);

+ 1 - 0
Source/Urho3D/LuaScript/pkgs/Resource/Image.pkg

@@ -36,6 +36,7 @@ class Image : public Resource
     bool SavePNG(const String fileName) const;
     bool SaveTGA(const String fileName) const;
     bool SaveJPG(const String fileName, int quality) const;
+    bool SaveDDS(const String fileName) const;
 
     Color GetPixel(int x, int y) const;
     Color GetPixel(int x, int y, int z) const;

+ 2 - 23
Source/Urho3D/LuaScript/pkgs/Resource/Resource.pkg

@@ -1,12 +1,11 @@
-$#include "IO/File.h"
 $#include "Resource/Resource.h"
 
 class Resource
 {
     bool Load(Deserializer& source);
     bool Save(Serializer& dest) const;
-    tolua_outside bool ResourceLoad @ Load(const String fileName);
-    tolua_outside bool ResourceSave @ Save(const String fileName) const;
+    bool Load(const String& fileName);
+    bool Save(const String& fileName) const;
     
     const String GetName() const;
     StringHash GetNameHash() const;
@@ -16,23 +15,3 @@ class Resource
     tolua_readonly tolua_property__get_set StringHash nameHash;
     tolua_readonly tolua_property__get_set unsigned memoryUse;
 };
-
-${
-static bool ResourceLoad(Resource* resource, const String& fileName)
-{
-    if (!resource)
-        return false;
-
-    File file(resource->GetContext());
-    return file.Open(fileName, FILE_READ) && resource->Load(file);
-}
-
-static bool ResourceSave(const Resource* resource, const String& fileName)
-{
-    if (!resource)
-        return false;
-
-    File file(resource->GetContext());
-    return file.Open(fileName, FILE_WRITE) && resource->Save(file);
-}
-$}

+ 48 - 35
Source/Urho3D/Math/MathDefs.h

@@ -71,6 +71,10 @@ inline bool Equals(T lhs, T rhs) { return lhs + std::numeric_limits<T>::epsilon(
 template <class T, class U>
 inline T Lerp(T lhs, T rhs, U t) { return lhs * (1.0 - t) + rhs * t; }
 
+/// Inverse linear interpolation between two values.
+template <class T>
+inline T InverseLerp(T lhs, T rhs, T x) { return (x - lhs) / (rhs - lhs); }
+
 /// Return the smaller of two values.
 template <class T, class U>
 inline T Min(T lhs, U rhs) { return lhs < rhs ? lhs : rhs; }
@@ -121,47 +125,56 @@ inline T SmoothStep(T lhs, T rhs, T t)
     return t * t * (3.0 - 2.0 * t);
 }
 
-/// Return sine of an angle in degrees. Uses sinf() for floats, sin() for
-/// everything else
-template <class T>
-inline T Sin(T angle) { return sin(angle * M_DEGTORAD); }
-template <> inline float Sin<float>(float angle) { return sinf(angle * M_DEGTORAD); }
+/// Return sine of an angle in degrees.
+template <class T> inline T Sin(T angle) { return sin(angle * M_DEGTORAD); }
 
-/// Return cosine of an angle in degrees. Uses cosf() for floats, cos() for
-/// everything else
-template <class T>
-inline T Cos(T angle) { return cos(angle * M_DEGTORAD); }
-template <> inline float Cos<float>(float angle) { return cosf(angle * M_DEGTORAD); }
+/// Return cosine of an angle in degrees.
+template <class T> inline T Cos(T angle) { return cos(angle * M_DEGTORAD); }
 
-/// Return tangent of an angle in degrees. Uses tanf() for floats, tan() for
-/// everything else
-template <class T>
-inline T Tan(T angle) { return tan(angle * M_DEGTORAD); }
-template <> inline float Tan<float>(float angle) { return tanf(angle * M_DEGTORAD); }
+/// Return tangent of an angle in degrees.
+template <class T> inline T Tan(T angle) { return tan(angle * M_DEGTORAD); }
 
-/// Return arc sine in degrees. Uses asinf() for floats, asin() for everything
-/// else
-template <class T>
-inline T Asin(T x) { return M_RADTODEG * asin(Clamp(x, -1.0, 1.0)); }
-template <> inline float Asin<float>(float x) { return M_RADTODEG * asinf(Clamp(x, -1.0f, 1.0f)); }
+/// Return arc sine in degrees.
+template <class T> inline T Asin(T x) { return M_RADTODEG * asin(Clamp(x, T(-1.0), T(1.0))); }
 
-/// Return arc cosine in degrees. Uses acosf() for floats, acos() for
-/// everything else
-template <class T>
-inline T Acos(T x) { return M_RADTODEG * acos(Clamp(x, -1.0, 1.0)); }
-template <> inline float Acos<float>(float x) { return M_RADTODEG * acosf(Clamp(x, -1.0f, 1.0f)); }
+/// Return arc cosine in degrees.
+template <class T> inline T Acos(T x) { return M_RADTODEG * acos(Clamp(x, T(-1.0), T(1.0))); }
 
-/// Return arc tangent in degrees. Uses atanf() for floats, atan() for
-/// everything else
-template <class T>
-inline T Atan(T x) { return M_RADTODEG * atan(x); }
-template <> inline float Atan<float>(float x) { return M_RADTODEG * atanf(x); }
+/// Return arc tangent in degrees.
+template <class T> inline T Atan(T x) { return M_RADTODEG * atan(x); }
 
-/// Return arc tangent of y/x in degrees. Uses atan2f() for floats, atan2()
-/// for everything else
-template <class T>
-inline T Atan2(T y, T x) { return M_RADTODEG * atan2(y, x); }
-template <> inline float Atan2<float>(float y, float x) { return M_RADTODEG * atan2f(y, x); }
+/// Return arc tangent of y/x in degrees.
+template <class T> inline T Atan2(T y, T x) { return M_RADTODEG * atan2(y, x); }
+
+/// Return X in power Y.
+template <class T> T Pow(T x, T y) { return pow(x, y); }
+
+/// Return square root of X.
+template <class T> T Sqrt(T x) { return sqrt(x); }
+
+/// Return floating-point remainder of X/Y.
+template <class T> T Mod(T x, T y) { return fmod(x, y); }
+
+/// Return fractional part of passed value in range [0, 1).
+template <class T> T Fract(T value) { return value - floor(value); }
+
+/// Round value down.
+template <class T> T Floor(T x) { return floor(x); }
+
+/// Round value down. Returns integer value.
+template <class T> int FloorToInt(T x) { return static_cast<int>(floor(x)); }
+
+/// Round value to nearest integer.
+template <class T> T Round(T x) { return floor(x + T(0.5)); }
+
+/// Round value to nearest integer.
+template <class T> int RoundToInt(T x) { return static_cast<int>(floor(x + T(0.5))); }
+
+/// Round value up.
+template <class T> T Ceil(T x) { return ceil(x); }
+
+/// Round value up.
+template <class T> int CeilToInt(T x) { return static_cast<int>(ceil(x)); }
 
 /// Check whether an unsigned integer is a power of two.
 inline bool IsPowerOfTwo(unsigned value)

+ 43 - 0
Source/Urho3D/Math/Vector2.h

@@ -168,6 +168,9 @@ public:
     /// Calculate absolute dot product.
     float AbsDotProduct(const Vector2& rhs) const { return Urho3D::Abs(x_ * rhs.x_) + Urho3D::Abs(y_ * rhs.y_); }
 
+    /// Project vector onto axis.
+    float ProjectOntoAxis(const Vector2& axis) const { return DotProduct(axis.Normalized()); }
+
     /// Returns the angle between this vector and another vector in degrees.
     float Angle(const Vector2& rhs) const { return Urho3D::Acos(DotProduct(rhs) / (Length() * rhs.Length())); }
 
@@ -338,4 +341,44 @@ public:
 /// Multiply IntVector2 with a scalar.
 inline IntVector2 operator *(int lhs, const IntVector2& rhs) { return rhs * lhs; }
 
+/// Per-component linear interpolation between two 2-vectors.
+inline Vector2 VectorLerp(const Vector2& lhs, const Vector2& rhs, const Vector2& t) { return lhs + (rhs - lhs) * t; }
+
+/// Per-component min of two 2-vectors.
+inline Vector2 VectorMin(const Vector2& lhs, const Vector2& rhs) { return Vector2(Min(lhs.x_, rhs.x_), Min(lhs.y_, rhs.y_)); }
+
+/// Per-component max of two 2-vectors.
+inline Vector2 VectorMax(const Vector2& lhs, const Vector2& rhs) { return Vector2(Max(lhs.x_, rhs.x_), Max(lhs.y_, rhs.y_)); }
+
+/// Per-component floor of 2-vector.
+inline Vector2 VectorFloor(const Vector2& vec) { return Vector2(Floor(vec.x_), Floor(vec.y_)); }
+
+/// Per-component round of 2-vector.
+inline Vector2 VectorRound(const Vector2& vec) { return Vector2(Round(vec.x_), Round(vec.y_)); }
+
+/// Per-component ceil of 2-vector.
+inline Vector2 VectorCeil(const Vector2& vec) { return Vector2(Ceil(vec.x_), Ceil(vec.y_)); }
+
+/// Per-component floor of 2-vector. Returns IntVector2.
+inline IntVector2 VectorFloorToInt(const Vector2& vec) { return IntVector2(FloorToInt(vec.x_), FloorToInt(vec.y_)); }
+
+/// Per-component round of 2-vector. Returns IntVector2.
+inline IntVector2 VectorRoundToInt(const Vector2& vec) { return IntVector2(RoundToInt(vec.x_), RoundToInt(vec.y_)); }
+
+/// Per-component ceil of 2-vector. Returns IntVector2.
+inline IntVector2 VectorCeilToInt(const Vector2& vec) { return IntVector2(CeilToInt(vec.x_), CeilToInt(vec.y_)); }
+
+/// Per-component min of two 2-vectors.
+inline IntVector2 VectorMin(const IntVector2& lhs, const IntVector2& rhs) { return IntVector2(Min(lhs.x_, rhs.x_), Min(lhs.y_, rhs.y_)); }
+
+/// Per-component max of two 2-vectors.
+inline IntVector2 VectorMax(const IntVector2& lhs, const IntVector2& rhs) { return IntVector2(Max(lhs.x_, rhs.x_), Max(lhs.y_, rhs.y_)); }
+
+/// Return a random value from [0, 1) from 2-vector seed.
+/// http://stackoverflow.com/questions/12964279/whats-the-origin-of-this-glsl-rand-one-liner
+inline float StableRandom(const Vector2& seed) { return Fract(Sin(seed.DotProduct(Vector2(12.9898f, 78.233f)) * M_RADTODEG) * 43758.5453f); }
+
+/// Return a random value from [0, 1) from scalar seed.
+inline float StableRandom(float seed) { return StableRandom(Vector2(seed, seed)); }
+
 }

+ 24 - 0
Source/Urho3D/Math/Vector3.h

@@ -206,6 +206,9 @@ public:
         return Urho3D::Abs(x_ * rhs.x_) + Urho3D::Abs(y_ * rhs.y_) + Urho3D::Abs(z_ * rhs.z_);
     }
 
+    /// Project vector onto axis.
+    float ProjectOntoAxis(const Vector3& axis) const { return DotProduct(axis.Normalized()); }
+
     /// Calculate cross product.
     Vector3 CrossProduct(const Vector3& rhs) const
     {
@@ -281,4 +284,25 @@ public:
 /// Multiply Vector3 with a scalar.
 inline Vector3 operator *(float lhs, const Vector3& rhs) { return rhs * lhs; }
 
+/// Per-component linear interpolation between two 3-vectors.
+inline Vector3 VectorLerp(const Vector3& lhs, const Vector3& rhs, const Vector3& t) { return lhs + (rhs - lhs) * t; }
+
+/// Per-component min of two 3-vectors.
+inline Vector3 VectorMin(const Vector3& lhs, const Vector3& rhs) { return Vector3(Min(lhs.x_, rhs.x_), Min(lhs.y_, rhs.y_), Min(lhs.z_, rhs.z_)); }
+
+/// Per-component max of two 3-vectors.
+inline Vector3 VectorMax(const Vector3& lhs, const Vector3& rhs) { return Vector3(Max(lhs.x_, rhs.x_), Max(lhs.y_, rhs.y_), Max(lhs.z_, rhs.z_)); }
+
+/// Per-component floor of 3-vector.
+inline Vector3 VectorFloor(const Vector3& vec) { return Vector3(Floor(vec.x_), Floor(vec.y_), Floor(vec.z_)); }
+
+/// Per-component round of 3-vector.
+inline Vector3 VectorRound(const Vector3& vec) { return Vector3(Round(vec.x_), Round(vec.y_), Round(vec.z_)); }
+
+/// Per-component ceil of 3-vector.
+inline Vector3 VectorCeil(const Vector3& vec) { return Vector3(Ceil(vec.x_), Ceil(vec.y_), Ceil(vec.z_)); }
+
+/// Return a random value from [0, 1) from 3-vector seed.
+inline float StableRandom(const Vector3& seed) { return StableRandom(Vector2(StableRandom(Vector2(seed.x_, seed.y_)), seed.z_)); }
+
 }

+ 21 - 0
Source/Urho3D/Math/Vector4.h

@@ -183,6 +183,9 @@ public:
         return Urho3D::Abs(x_ * rhs.x_) + Urho3D::Abs(y_ * rhs.y_) + Urho3D::Abs(z_ * rhs.z_) + Urho3D::Abs(w_ * rhs.w_);
     }
 
+    /// Project vector onto axis.
+    float ProjectOntoAxis(const Vector3& axis) const { return DotProduct(Vector4(axis.Normalized(), 0.0f)); }
+
     /// Return absolute vector.
     Vector4 Abs() const { return Vector4(Urho3D::Abs(x_), Urho3D::Abs(y_), Urho3D::Abs(z_), Urho3D::Abs(w_)); }
 
@@ -222,4 +225,22 @@ public:
 /// Multiply Vector4 with a scalar.
 inline Vector4 operator *(float lhs, const Vector4& rhs) { return rhs * lhs; }
 
+/// Per-component linear interpolation between two 4-vectors.
+inline Vector4 VectorLerp(const Vector4& lhs, const Vector4& rhs, const Vector4& t) { return lhs + (rhs - lhs) * t; }
+
+/// Per-component min of two 4-vectors.
+inline Vector4 VectorMin(const Vector4& lhs, const Vector4& rhs) { return Vector4(Min(lhs.x_, rhs.x_), Min(lhs.y_, rhs.y_), Min(lhs.z_, rhs.z_), Min(lhs.w_, rhs.w_)); }
+
+/// Per-component max of two 4-vectors.
+inline Vector4 VectorMax(const Vector4& lhs, const Vector4& rhs) { return Vector4(Max(lhs.x_, rhs.x_), Max(lhs.y_, rhs.y_), Max(lhs.z_, rhs.z_), Max(lhs.w_, rhs.w_)); }
+
+/// Per-component floor of 4-vector.
+inline Vector4 VectorFloor(const Vector4& vec) { return Vector4(Floor(vec.x_), Floor(vec.y_), Floor(vec.z_), Floor(vec.w_)); }
+
+/// Per-component round of 4-vector.
+inline Vector4 VectorRound(const Vector4& vec) { return Vector4(Round(vec.x_), Round(vec.y_), Round(vec.z_), Round(vec.w_)); }
+
+/// Per-component ceil of 4-vector.
+inline Vector4 VectorCeil(const Vector4& vec) { return Vector4(Ceil(vec.x_), Ceil(vec.y_), Ceil(vec.z_), Ceil(vec.w_)); }
+
 }

+ 4 - 10
Source/Urho3D/Navigation/DynamicNavigationMesh.cpp

@@ -226,12 +226,6 @@ DynamicNavigationMesh::DynamicNavigationMesh(Context* context) :
 DynamicNavigationMesh::~DynamicNavigationMesh()
 {
     ReleaseNavigationMesh();
-    delete allocator_;
-    allocator_ = 0;
-    delete compressor_;
-    compressor_ = 0;
-    delete meshProcessor_;
-    meshProcessor_ = 0;
 }
 
 void DynamicNavigationMesh::RegisterObject(Context* context)
@@ -336,7 +330,7 @@ bool DynamicNavigationMesh::Build()
             return false;
         }
 
-        if (dtStatusFailed(tileCache_->init(&tileCacheParams, allocator_, compressor_, meshProcessor_)))
+        if (dtStatusFailed(tileCache_->init(&tileCacheParams, allocator_.Get(), compressor_.Get(), meshProcessor_.Get())))
         {
             URHO3D_LOGERROR("Could not initialize tile cache");
             ReleaseNavigationMesh();
@@ -595,7 +589,7 @@ void DynamicNavigationMesh::SetNavigationDataAttr(const PODVector<unsigned char>
         ReleaseNavigationMesh();
         return;
     }
-    if (dtStatusFailed(tileCache_->init(&tcParams, allocator_, compressor_, meshProcessor_)))
+    if (dtStatusFailed(tileCache_->init(&tcParams, allocator_.Get(), compressor_.Get(), meshProcessor_.Get())))
     {
         URHO3D_LOGERROR("Could not initialize tile cache");
         ReleaseNavigationMesh();
@@ -688,7 +682,7 @@ int DynamicNavigationMesh::BuildTile(Vector<NavigationGeometryInfo>& geometryLis
             boundingBox_.max_.y_,
             boundingBox_.min_.z_ + tileEdgeLength * (float)(z + 1)));
 
-    DynamicNavBuildData build(allocator_);
+    DynamicNavBuildData build(allocator_.Get());
 
     rcConfig cfg;
     memset(&cfg, 0, sizeof cfg);
@@ -835,7 +829,7 @@ int DynamicNavigationMesh::BuildTile(Vector<NavigationGeometryInfo>& geometryLis
         header.hmax = (unsigned short)layer->hmax;
 
         if (dtStatusFailed(
-            dtBuildTileCacheLayer(compressor_/*compressor*/, &header, layer->heights, layer->areas/*areas*/, layer->cons,
+            dtBuildTileCacheLayer(compressor_.Get()/*compressor*/, &header, layer->heights, layer->areas/*areas*/, layer->cons,
                 &(tiles[retCt].data), &tiles[retCt].dataSize)))
         {
             URHO3D_LOGERROR("Failed to build tile cache layers");

+ 3 - 3
Source/Urho3D/Navigation/DynamicNavigationMesh.h

@@ -113,11 +113,11 @@ private:
     /// Detour tile cache instance that works with the nav mesh.
     dtTileCache* tileCache_;
     /// Used by dtTileCache to allocate blocks of memory.
-    dtTileCacheAlloc* allocator_;
+    UniquePtr<dtTileCacheAlloc> allocator_;
     /// Used by dtTileCache to compress the original tiles to use when reconstructing for changes.
-    dtTileCacheCompressor* compressor_;
+    UniquePtr<dtTileCacheCompressor> compressor_;
     /// Mesh processer used by Detour, in this case a 'pass-through' processor.
-    dtTileCacheMeshProcess* meshProcessor_;
+    UniquePtr<dtTileCacheMeshProcess> meshProcessor_;
     /// Maximum number of obstacle objects allowed.
     unsigned maxObstacles_;
     /// Maximum number of layers that are allowed to be constructed.

+ 7 - 13
Source/Urho3D/Navigation/NavigationMesh.cpp

@@ -129,12 +129,6 @@ NavigationMesh::NavigationMesh(Context* context) :
 NavigationMesh::~NavigationMesh()
 {
     ReleaseNavigationMesh();
-
-    delete queryFilter_;
-    queryFilter_ = 0;
-
-    delete pathData_;
-    pathData_ = 0;
 }
 
 void NavigationMesh::RegisterObject(Context* context)
@@ -488,7 +482,7 @@ Vector3 NavigationMesh::FindNearestPoint(const Vector3& point, const Vector3& ex
     dtPolyRef pointRef;
     if (!nearestRef)
         nearestRef = &pointRef;
-    navMeshQuery_->findNearestPoly(&localPoint.x_, &extents.x_, filter ? filter : queryFilter_, nearestRef, &nearestPoint.x_);
+    navMeshQuery_->findNearestPoly(&localPoint.x_, &extents.x_, filter ? filter : queryFilter_.Get(), nearestRef, &nearestPoint.x_);
     return *nearestRef ? transform * nearestPoint : point;
 }
 
@@ -504,7 +498,7 @@ Vector3 NavigationMesh::MoveAlongSurface(const Vector3& start, const Vector3& en
     Vector3 localStart = inverse * start;
     Vector3 localEnd = inverse * end;
 
-    const dtQueryFilter* queryFilter = filter ? filter : queryFilter_;
+    const dtQueryFilter* queryFilter = filter ? filter : queryFilter_.Get();
     dtPolyRef startRef;
     navMeshQuery_->findNearestPoly(&localStart.x_, &extents.x_, queryFilter, &startRef, 0);
     if (!startRef)
@@ -546,7 +540,7 @@ void NavigationMesh::FindPath(PODVector<NavigationPathPoint>& dest, const Vector
     Vector3 localStart = inverse * start;
     Vector3 localEnd = inverse * end;
 
-    const dtQueryFilter* queryFilter = filter ? filter : queryFilter_;
+    const dtQueryFilter* queryFilter = filter ? filter : queryFilter_.Get();
     dtPolyRef startRef;
     dtPolyRef endRef;
     navMeshQuery_->findNearestPoly(&localStart.x_, &extents.x_, queryFilter, &startRef, 0);
@@ -614,7 +608,7 @@ Vector3 NavigationMesh::GetRandomPoint(const dtQueryFilter* filter, dtPolyRef* r
     dtPolyRef polyRef;
     Vector3 point(Vector3::ZERO);
 
-    navMeshQuery_->findRandomPoint(filter ? filter : queryFilter_, Random, randomRef ? randomRef : &polyRef, &point.x_);
+    navMeshQuery_->findRandomPoint(filter ? filter : queryFilter_.Get(), Random, randomRef ? randomRef : &polyRef, &point.x_);
 
     return node_->GetWorldTransform() * point;
 }
@@ -632,7 +626,7 @@ Vector3 NavigationMesh::GetRandomPointInCircle(const Vector3& center, float radi
     Matrix3x4 inverse = transform.Inverse();
     Vector3 localCenter = inverse * center;
 
-    const dtQueryFilter* queryFilter = filter ? filter : queryFilter_;
+    const dtQueryFilter* queryFilter = filter ? filter : queryFilter_.Get();
     dtPolyRef startRef;
     navMeshQuery_->findNearestPoly(&localCenter.x_, &extents.x_, queryFilter, &startRef, 0);
     if (!startRef)
@@ -663,7 +657,7 @@ float NavigationMesh::GetDistanceToWall(const Vector3& point, float radius, cons
     Matrix3x4 inverse = transform.Inverse();
     Vector3 localPoint = inverse * point;
 
-    const dtQueryFilter* queryFilter = filter ? filter : queryFilter_;
+    const dtQueryFilter* queryFilter = filter ? filter : queryFilter_.Get();
     dtPolyRef startRef;
     navMeshQuery_->findNearestPoly(&localPoint.x_, &extents.x_, queryFilter, &startRef, 0);
     if (!startRef)
@@ -696,7 +690,7 @@ Vector3 NavigationMesh::Raycast(const Vector3& start, const Vector3& end, const
     Vector3 localStart = inverse * start;
     Vector3 localEnd = inverse * end;
 
-    const dtQueryFilter* queryFilter = filter ? filter : queryFilter_;
+    const dtQueryFilter* queryFilter = filter ? filter : queryFilter_.Get();
     dtPolyRef startRef;
     navMeshQuery_->findNearestPoly(&localStart.x_, &extents.x_, queryFilter, &startRef, 0);
     if (!startRef)

+ 2 - 2
Source/Urho3D/Navigation/NavigationMesh.h

@@ -278,9 +278,9 @@ protected:
     /// Detour navigation mesh query.
     dtNavMeshQuery* navMeshQuery_;
     /// Detour navigation mesh query filter.
-    dtQueryFilter* queryFilter_;
+    UniquePtr<dtQueryFilter> queryFilter_;
     /// Temporary data for finding a path.
-    FindPathData* pathData_;
+    UniquePtr<FindPathData> pathData_;
     /// Tile size.
     int tileSize_;
     /// Cell size.

+ 0 - 3
Source/Urho3D/Network/Network.cpp

@@ -114,9 +114,6 @@ Network::~Network()
     serverConnection_.Reset();
 
     clientConnections_.Clear();
-
-    delete network_;
-    network_ = 0;
 }
 
 void Network::HandleMessage(kNet::MessageConnection* source, kNet::packet_id_t packetId, kNet::message_id_t msgId, const char* data,

+ 1 - 1
Source/Urho3D/Network/Network.h

@@ -147,7 +147,7 @@ private:
     void ConfigureNetworkSimulator();
 
     /// kNet instance.
-    kNet::Network* network_;
+    UniquePtr<kNet::Network> network_;
     /// Client's server connection.
     SharedPtr<Connection> serverConnection_;
     /// Server's client connections.

+ 13 - 29
Source/Urho3D/Physics/CollisionShape.cpp

@@ -194,40 +194,26 @@ private:
     Vector<SharedArrayPtr<unsigned char> > dataArrays_;
 };
 
-TriangleMeshData::TriangleMeshData(Model* model, unsigned lodLevel) :
-    meshInterface_(0),
-    shape_(0),
-    infoMap_(0)
+TriangleMeshData::TriangleMeshData(Model* model, unsigned lodLevel)
 {
     meshInterface_ = new TriangleMeshInterface(model, lodLevel);
-    shape_ = new btBvhTriangleMeshShape(meshInterface_, meshInterface_->useQuantize_, true);
+    shape_ = new btBvhTriangleMeshShape(meshInterface_.Get(), meshInterface_->useQuantize_, true);
 
     infoMap_ = new btTriangleInfoMap();
-    btGenerateInternalEdgeInfo(shape_, infoMap_);
+    btGenerateInternalEdgeInfo(shape_.Get(), infoMap_.Get());
 }
 
-TriangleMeshData::TriangleMeshData(CustomGeometry* custom) :
-    meshInterface_(0),
-    shape_(0),
-    infoMap_(0)
+TriangleMeshData::TriangleMeshData(CustomGeometry* custom)
 {
     meshInterface_ = new TriangleMeshInterface(custom);
-    shape_ = new btBvhTriangleMeshShape(meshInterface_, meshInterface_->useQuantize_, true);
+    shape_ = new btBvhTriangleMeshShape(meshInterface_.Get(), meshInterface_->useQuantize_, true);
 
     infoMap_ = new btTriangleInfoMap();
-    btGenerateInternalEdgeInfo(shape_, infoMap_);
+    btGenerateInternalEdgeInfo(shape_.Get(), infoMap_.Get());
 }
 
 TriangleMeshData::~TriangleMeshData()
 {
-    delete shape_;
-    shape_ = 0;
-
-    delete meshInterface_;
-    meshInterface_ = 0;
-
-    delete infoMap_;
-    infoMap_ = 0;
 }
 
 ConvexData::ConvexData(Model* model, unsigned lodLevel)
@@ -410,7 +396,6 @@ bool HasDynamicBuffers(Model* model, unsigned lodLevel)
 
 CollisionShape::CollisionShape(Context* context) :
     Component(context),
-    shape_(0),
     shapeType_(SHAPE_BOX),
     position_(Vector3::ZERO),
     rotation_(Quaternion::IDENTITY),
@@ -501,7 +486,7 @@ void CollisionShape::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
         Quaternion worldRotation(worldTransform.Rotation() * rotation_);
 
         btDiscreteDynamicsWorld* world = physicsWorld_->GetWorld();
-        world->debugDrawObject(btTransform(ToBtQuaternion(worldRotation), ToBtVector3(worldPosition)), shape_, bodyActive ?
+        world->debugDrawObject(btTransform(ToBtQuaternion(worldRotation), ToBtVector3(worldPosition)), shape_.Get(), bodyActive ?
             WHITE : GREEN);
 
         physicsWorld_->SetDebugRenderer(0);
@@ -863,7 +848,7 @@ void CollisionShape::NotifyRigidBody(bool updateMass)
     if (node_ && shape_ && compound)
     {
         // Remove the shape first to ensure it is not added twice
-        compound->removeChildShape(shape_);
+        compound->removeChildShape(shape_.Get());
 
         if (IsEnabledEffective())
         {
@@ -879,7 +864,7 @@ void CollisionShape::NotifyRigidBody(bool updateMass)
             btTransform offset;
             offset.setOrigin(ToBtVector3(node_->GetWorldScale() * position));
             offset.setRotation(ToBtQuaternion(rotation_));
-            compound->addChildShape(offset, shape_);
+            compound->addChildShape(offset, shape_.Get());
         }
 
         // Finally tell the rigid body to update its mass
@@ -906,12 +891,11 @@ void CollisionShape::ReleaseShape()
     btCompoundShape* compound = GetParentCompoundShape();
     if (shape_ && compound)
     {
-        compound->removeChildShape(shape_);
+        compound->removeChildShape(shape_.Get());
         rigidBody_->UpdateMass();
     }
 
-    delete shape_;
-    shape_ = 0;
+    shape_.Reset();
 
     geometry_.Reset();
 
@@ -1072,7 +1056,7 @@ void CollisionShape::UpdateShape()
                 {
                     geometry_ = new TriangleMeshData(custom);
                     TriangleMeshData* triMesh = static_cast<TriangleMeshData*>(geometry_.Get());
-                    shape_ = new btScaledBvhTriangleMeshShape(triMesh->shape_, ToBtVector3(newWorldScale * size_));
+                    shape_ = new btScaledBvhTriangleMeshShape(triMesh->shape_.Get(), ToBtVector3(newWorldScale * size_));
                 }
                 else
                     URHO3D_LOGWARNING("Could not find custom geometry component ID " + String(customGeometryID_) +
@@ -1095,7 +1079,7 @@ void CollisionShape::UpdateShape()
                 }
 
                 TriangleMeshData* triMesh = static_cast<TriangleMeshData*>(geometry_.Get());
-                shape_ = new btScaledBvhTriangleMeshShape(triMesh->shape_, ToBtVector3(newWorldScale * size_));
+                shape_ = new btScaledBvhTriangleMeshShape(triMesh->shape_.Get(), ToBtVector3(newWorldScale * size_));
                 // Watch for live reloads of the collision model to reload the geometry if necessary
                 SubscribeToEvent(model_, E_RELOADFINISHED, URHO3D_HANDLER(CollisionShape, HandleModelReloadFinished));
             }

+ 5 - 5
Source/Urho3D/Physics/CollisionShape.h

@@ -75,11 +75,11 @@ struct TriangleMeshData : public CollisionGeometryData
     ~TriangleMeshData();
 
     /// Bullet triangle mesh interface.
-    TriangleMeshInterface* meshInterface_;
+    UniquePtr<TriangleMeshInterface> meshInterface_;
     /// Bullet triangle mesh collision shape.
-    btBvhTriangleMeshShape* shape_;
+    UniquePtr<btBvhTriangleMeshShape> shape_;
     /// Bullet triangle info map.
-    btTriangleInfoMap* infoMap_;
+    UniquePtr<btTriangleInfoMap> infoMap_;
 };
 
 /// Convex hull geometry data.
@@ -196,7 +196,7 @@ public:
     void SetLodLevel(unsigned lodLevel);
 
     /// Return Bullet collision shape.
-    btCollisionShape* GetCollisionShape() const { return shape_; }
+    btCollisionShape* GetCollisionShape() const { return shape_.Get(); }
 
     /// Return the shared geometry data.
     CollisionGeometryData* GetGeometryData() const { return geometry_; }
@@ -272,7 +272,7 @@ private:
     /// Shared geometry data.
     SharedPtr<CollisionGeometryData> geometry_;
     /// Bullet collision shape.
-    btCollisionShape* shape_;
+    UniquePtr<btCollisionShape> shape_;
     /// Collision shape type.
     ShapeType shapeType_;
     /// Offset position.

+ 11 - 13
Source/Urho3D/Physics/Constraint.cpp

@@ -54,7 +54,6 @@ extern const char* PHYSICS_CATEGORY;
 
 Constraint::Constraint(Context* context) :
     Component(context),
-    constraint_(0),
     constraintType_(CONSTRAINT_POINT),
     position_(Vector3::ZERO),
     rotation_(Quaternion::IDENTITY),
@@ -167,7 +166,7 @@ void Constraint::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
     {
         physicsWorld_->SetDebugRenderer(debug);
         physicsWorld_->SetDebugDepthTest(depthTest);
-        physicsWorld_->GetWorld()->debugDrawConstraint(constraint_);
+        physicsWorld_->GetWorld()->debugDrawConstraint(constraint_.Get());
         physicsWorld_->SetDebugRenderer(0);
     }
 }
@@ -380,10 +379,9 @@ void Constraint::ReleaseConstraint()
             otherBody_->RemoveConstraint(this);
 
         if (physicsWorld_)
-            physicsWorld_->GetWorld()->removeConstraint(constraint_);
+            physicsWorld_->GetWorld()->removeConstraint(constraint_.Get());
 
-        delete constraint_;
-        constraint_ = 0;
+        constraint_.Reset();
     }
 }
 
@@ -402,7 +400,7 @@ void Constraint::ApplyFrames()
     {
     case POINT2POINT_CONSTRAINT_TYPE:
         {
-            btPoint2PointConstraint* pointConstraint = static_cast<btPoint2PointConstraint*>(constraint_);
+            btPoint2PointConstraint* pointConstraint = static_cast<btPoint2PointConstraint*>(constraint_.Get());
             pointConstraint->setPivotA(ToBtVector3(ownBodyScaledPosition));
             pointConstraint->setPivotB(ToBtVector3(otherBodyScaledPosition));
         }
@@ -410,7 +408,7 @@ void Constraint::ApplyFrames()
 
     case HINGE_CONSTRAINT_TYPE:
         {
-            btHingeConstraint* hingeConstraint = static_cast<btHingeConstraint*>(constraint_);
+            btHingeConstraint* hingeConstraint = static_cast<btHingeConstraint*>(constraint_.Get());
             btTransform ownFrame(ToBtQuaternion(rotation_), ToBtVector3(ownBodyScaledPosition));
             btTransform otherFrame(ToBtQuaternion(otherRotation_), ToBtVector3(otherBodyScaledPosition));
             hingeConstraint->setFrames(ownFrame, otherFrame);
@@ -419,7 +417,7 @@ void Constraint::ApplyFrames()
 
     case SLIDER_CONSTRAINT_TYPE:
         {
-            btSliderConstraint* sliderConstraint = static_cast<btSliderConstraint*>(constraint_);
+            btSliderConstraint* sliderConstraint = static_cast<btSliderConstraint*>(constraint_.Get());
             btTransform ownFrame(ToBtQuaternion(rotation_), ToBtVector3(ownBodyScaledPosition));
             btTransform otherFrame(ToBtQuaternion(otherRotation_), ToBtVector3(otherBodyScaledPosition));
             sliderConstraint->setFrames(ownFrame, otherFrame);
@@ -428,7 +426,7 @@ void Constraint::ApplyFrames()
 
     case CONETWIST_CONSTRAINT_TYPE:
         {
-            btConeTwistConstraint* coneTwistConstraint = static_cast<btConeTwistConstraint*>(constraint_);
+            btConeTwistConstraint* coneTwistConstraint = static_cast<btConeTwistConstraint*>(constraint_.Get());
             btTransform ownFrame(ToBtQuaternion(rotation_), ToBtVector3(ownBodyScaledPosition));
             btTransform otherFrame(ToBtQuaternion(otherRotation_), ToBtVector3(otherBodyScaledPosition));
             coneTwistConstraint->setFrames(ownFrame, otherFrame);
@@ -555,7 +553,7 @@ void Constraint::CreateConstraint()
 
         ApplyLimits();
 
-        physicsWorld_->GetWorld()->addConstraint(constraint_, disableCollision_);
+        physicsWorld_->GetWorld()->addConstraint(constraint_.Get(), disableCollision_);
     }
 
     recreateConstraint_ = false;
@@ -572,14 +570,14 @@ void Constraint::ApplyLimits()
     {
     case HINGE_CONSTRAINT_TYPE:
         {
-            btHingeConstraint* hingeConstraint = static_cast<btHingeConstraint*>(constraint_);
+            btHingeConstraint* hingeConstraint = static_cast<btHingeConstraint*>(constraint_.Get());
             hingeConstraint->setLimit(lowLimit_.x_ * M_DEGTORAD, highLimit_.x_ * M_DEGTORAD);
         }
         break;
 
     case SLIDER_CONSTRAINT_TYPE:
         {
-            btSliderConstraint* sliderConstraint = static_cast<btSliderConstraint*>(constraint_);
+            btSliderConstraint* sliderConstraint = static_cast<btSliderConstraint*>(constraint_.Get());
             sliderConstraint->setUpperLinLimit(highLimit_.x_);
             sliderConstraint->setUpperAngLimit(highLimit_.y_ * M_DEGTORAD);
             sliderConstraint->setLowerLinLimit(lowLimit_.x_);
@@ -589,7 +587,7 @@ void Constraint::ApplyLimits()
 
     case CONETWIST_CONSTRAINT_TYPE:
         {
-            btConeTwistConstraint* coneTwistConstraint = static_cast<btConeTwistConstraint*>(constraint_);
+            btConeTwistConstraint* coneTwistConstraint = static_cast<btConeTwistConstraint*>(constraint_.Get());
             coneTwistConstraint->setLimit(highLimit_.y_ * M_DEGTORAD, highLimit_.y_ * M_DEGTORAD, highLimit_.x_ * M_DEGTORAD);
         }
         break;

+ 2 - 2
Source/Urho3D/Physics/Constraint.h

@@ -101,7 +101,7 @@ public:
     PhysicsWorld* GetPhysicsWorld() const { return physicsWorld_; }
 
     /// Return Bullet constraint.
-    btTypedConstraint* GetConstraint() const { return constraint_; }
+    btTypedConstraint* GetConstraint() const { return constraint_.Get(); }
 
     /// Return constraint type.
     ConstraintType GetConstraintType() const { return constraintType_; }
@@ -168,7 +168,7 @@ private:
     /// Other rigid body.
     WeakPtr<RigidBody> otherBody_;
     /// Bullet constraint.
-    btTypedConstraint* constraint_;
+    UniquePtr<btTypedConstraint> constraint_;
     /// Constraint type.
     ConstraintType constraintType_;
     /// Constraint position.

+ 13 - 26
Source/Urho3D/Physics/PhysicsWorld.cpp

@@ -120,10 +120,6 @@ struct PhysicsQueryCallback : public btCollisionWorld::ContactResultCallback
 PhysicsWorld::PhysicsWorld(Context* context) :
     Component(context),
     collisionConfiguration_(0),
-    collisionDispatcher_(0),
-    broadphase_(0),
-    solver_(0),
-    world_(0),
     fps_(DEFAULT_FPS),
     maxSubSteps_(0),
     timeAcc_(0.0f),
@@ -146,7 +142,7 @@ PhysicsWorld::PhysicsWorld(Context* context) :
     collisionDispatcher_ = new btCollisionDispatcher(collisionConfiguration_);
     broadphase_ = new btDbvtBroadphase();
     solver_ = new btSequentialImpulseConstraintSolver();
-    world_ = new btDiscreteDynamicsWorld(collisionDispatcher_, broadphase_, solver_, collisionConfiguration_);
+    world_ = new btDiscreteDynamicsWorld(collisionDispatcher_.Get(), broadphase_.Get(), solver_.Get(), collisionConfiguration_);
 
     world_->setGravity(ToBtVector3(DEFAULT_GRAVITY));
     world_->getDispatchInfo().m_useContinuous = true;
@@ -172,17 +168,10 @@ PhysicsWorld::~PhysicsWorld()
             (*i)->ReleaseShape();
     }
 
-    delete world_;
-    world_ = 0;
-
-    delete solver_;
-    solver_ = 0;
-
-    delete broadphase_;
-    broadphase_ = 0;
-
-    delete collisionDispatcher_;
-    collisionDispatcher_ = 0;
+    world_.Reset();
+    solver_.Reset();
+    broadphase_.Reset();
+    collisionDispatcher_.Reset();
 
     // Delete configuration only if it was the default created by PhysicsWorld
     if (!PhysicsWorld::config.collisionConfig_)
@@ -623,17 +612,16 @@ void PhysicsWorld::GetRigidBodies(PODVector<RigidBody*>& result, const Sphere& s
     result.Clear();
 
     btSphereShape sphereShape(sphere.radius_);
-    btRigidBody* tempRigidBody = new btRigidBody(1.0f, 0, &sphereShape);
+    UniquePtr<btRigidBody> tempRigidBody(new btRigidBody(1.0f, 0, &sphereShape));
     tempRigidBody->setWorldTransform(btTransform(btQuaternion::getIdentity(), ToBtVector3(sphere.center_)));
     // Need to activate the temporary rigid body to get reliable results from static, sleeping objects
     tempRigidBody->activate();
-    world_->addRigidBody(tempRigidBody);
+    world_->addRigidBody(tempRigidBody.Get());
 
     PhysicsQueryCallback callback(result, collisionMask);
-    world_->contactTest(tempRigidBody, callback);
+    world_->contactTest(tempRigidBody.Get(), callback);
 
-    world_->removeRigidBody(tempRigidBody);
-    delete tempRigidBody;
+    world_->removeRigidBody(tempRigidBody.Get());
 }
 
 void PhysicsWorld::GetRigidBodies(PODVector<RigidBody*>& result, const BoundingBox& box, unsigned collisionMask)
@@ -643,16 +631,15 @@ void PhysicsWorld::GetRigidBodies(PODVector<RigidBody*>& result, const BoundingB
     result.Clear();
 
     btBoxShape boxShape(ToBtVector3(box.HalfSize()));
-    btRigidBody* tempRigidBody = new btRigidBody(1.0f, 0, &boxShape);
+    UniquePtr<btRigidBody> tempRigidBody(new btRigidBody(1.0f, 0, &boxShape));
     tempRigidBody->setWorldTransform(btTransform(btQuaternion::getIdentity(), ToBtVector3(box.Center())));
     tempRigidBody->activate();
-    world_->addRigidBody(tempRigidBody);
+    world_->addRigidBody(tempRigidBody.Get());
 
     PhysicsQueryCallback callback(result, collisionMask);
-    world_->contactTest(tempRigidBody, callback);
+    world_->contactTest(tempRigidBody.Get(), callback);
 
-    world_->removeRigidBody(tempRigidBody);
-    delete tempRigidBody;
+    world_->removeRigidBody(tempRigidBody.Get());
 }
 
 void PhysicsWorld::GetRigidBodies(PODVector<RigidBody*>& result, const RigidBody* body)

+ 5 - 5
Source/Urho3D/Physics/PhysicsWorld.h

@@ -261,7 +261,7 @@ public:
     void SetDebugDepthTest(bool enable);
 
     /// Return the Bullet physics world.
-    btDiscreteDynamicsWorld* GetWorld() { return world_; }
+    btDiscreteDynamicsWorld* GetWorld() { return world_.Get(); }
 
     /// Clean up the geometry cache.
     void CleanupGeometryCache();
@@ -301,13 +301,13 @@ private:
     /// Bullet collision configuration.
     btCollisionConfiguration* collisionConfiguration_;
     /// Bullet collision dispatcher.
-    btDispatcher* collisionDispatcher_;
+    UniquePtr<btDispatcher> collisionDispatcher_;
     /// Bullet collision broadphase.
-    btBroadphaseInterface* broadphase_;
+    UniquePtr<btBroadphaseInterface> broadphase_;
     /// Bullet constraint solver.
-    btConstraintSolver* solver_;
+    UniquePtr<btConstraintSolver> solver_;
     /// Bullet physics world.
-    btDiscreteDynamicsWorld* world_;
+    UniquePtr<btDiscreteDynamicsWorld> world_;
     /// Extra weak pointer to scene to allow for cleanup in case the world is destroyed before other components.
     WeakPtr<Scene> scene_;
     /// Rigid bodies in the world.

+ 6 - 15
Source/Urho3D/Physics/RigidBody.cpp

@@ -63,9 +63,6 @@ extern const char* PHYSICS_CATEGORY;
 
 RigidBody::RigidBody(Context* context) :
     Component(context),
-    body_(0),
-    compoundShape_(0),
-    shiftedCompoundShape_(0),
     gravityOverride_(Vector3::ZERO),
     centerOfMass_(Vector3::ZERO),
     mass_(DEFAULT_MASS),
@@ -92,11 +89,6 @@ RigidBody::~RigidBody()
 
     if (physicsWorld_)
         physicsWorld_->RemoveRigidBody(this);
-
-    delete compoundShape_;
-    compoundShape_ = 0;
-    delete shiftedCompoundShape_;
-    shiftedCompoundShape_ = 0;
 }
 
 void RigidBody::RegisterObject(Context* context)
@@ -218,7 +210,7 @@ void RigidBody::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
         physicsWorld_->SetDebugDepthTest(depthTest);
 
         btDiscreteDynamicsWorld* world = physicsWorld_->GetWorld();
-        world->debugDrawObject(body_->getWorldTransform(), shiftedCompoundShape_, IsActive() ? btVector3(1.0f, 1.0f, 1.0f) :
+        world->debugDrawObject(body_->getWorldTransform(), shiftedCompoundShape_.Get(), IsActive() ? btVector3(1.0f, 1.0f, 1.0f) :
             btVector3(0.0f, 1.0f, 0.0f));
 
         physicsWorld_->SetDebugRenderer(0);
@@ -794,7 +786,7 @@ void RigidBody::UpdateMass()
             !ToQuaternion(childTransform.getRotation()).Equals(Quaternion::IDENTITY))
             useCompound = true;
     }
-    body_->setCollisionShape(useCompound ? shiftedCompoundShape_ : shiftedCompoundShape_->getChildShape(0));
+    body_->setCollisionShape(useCompound ? shiftedCompoundShape_.Get() : shiftedCompoundShape_->getChildShape(0));
 
     // If we have one shape and this is a triangle mesh, we use a custom material callback in order to adjust internal edges
     if (!useCompound && body_->getCollisionShape()->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE &&
@@ -888,8 +880,7 @@ void RigidBody::ReleaseBody()
 
         RemoveBodyFromWorld();
 
-        delete body_;
-        body_ = 0;
+        body_.Reset();
     }
 }
 
@@ -970,7 +961,7 @@ void RigidBody::AddBodyToWorld()
     {
         // Correct inertia will be calculated below
         btVector3 localInertia(0.0f, 0.0f, 0.0f);
-        body_ = new btRigidBody(mass_, this, shiftedCompoundShape_, localInertia);
+        body_ = new btRigidBody(mass_, this, shiftedCompoundShape_.Get(), localInertia);
         body_->setUserPointer(this);
 
         // Check for existence of the SmoothedTransform component, which should be created by now in network client mode.
@@ -1016,7 +1007,7 @@ void RigidBody::AddBodyToWorld()
         return;
 
     btDiscreteDynamicsWorld* world = physicsWorld_->GetWorld();
-    world->addRigidBody(body_, (short)collisionLayer_, (short)collisionMask_);
+    world->addRigidBody(body_.Get(), (short)collisionLayer_, (short)collisionMask_);
     inWorld_ = true;
     readdBody_ = false;
     hasSimulated_ = false;
@@ -1035,7 +1026,7 @@ void RigidBody::RemoveBodyFromWorld()
     if (physicsWorld_ && body_ && inWorld_)
     {
         btDiscreteDynamicsWorld* world = physicsWorld_->GetWorld();
-        world->removeRigidBody(body_);
+        world->removeRigidBody(body_.Get());
         inWorld_ = false;
     }
 }

+ 5 - 5
Source/Urho3D/Physics/RigidBody.h

@@ -153,10 +153,10 @@ public:
     PhysicsWorld* GetPhysicsWorld() const { return physicsWorld_; }
 
     /// Return Bullet rigid body.
-    btRigidBody* GetBody() const { return body_; }
+    btRigidBody* GetBody() const { return body_.Get(); }
 
     /// Return Bullet compound collision shape.
-    btCompoundShape* GetCompoundShape() const { return compoundShape_; }
+    btCompoundShape* GetCompoundShape() const { return compoundShape_.Get(); }
 
     /// Return mass.
     float GetMass() const { return mass_; }
@@ -264,11 +264,11 @@ private:
     void HandleTargetRotation(StringHash eventType, VariantMap& eventData);
 
     /// Bullet rigid body.
-    btRigidBody* body_;
+    UniquePtr<btRigidBody> body_;
     /// Bullet compound collision shape.
-    btCompoundShape* compoundShape_;
+    UniquePtr<btCompoundShape> compoundShape_;
     /// Compound collision shape with center of mass offset applied.
-    btCompoundShape* shiftedCompoundShape_;
+    UniquePtr<btCompoundShape> shiftedCompoundShape_;
     /// Physics world.
     WeakPtr<PhysicsWorld> physicsWorld_;
     /// Smoothed transform, if has one.

+ 65 - 0
Source/Urho3D/Resource/Image.cpp

@@ -775,6 +775,19 @@ bool Image::Save(Serializer& dest) const
     return success;
 }
 
+bool Image::Save(const String& fileName) const
+{
+    if (fileName.EndsWith(".dds", false))
+        return SaveDDS(fileName);
+    else if (fileName.EndsWith(".bmp", false))
+        return SaveBMP(fileName);
+    else if (fileName.EndsWith(".jpg", false) || fileName.EndsWith(".jpeg", false))
+        return SaveJPG(fileName, 100);
+    else if (fileName.EndsWith(".tga", false))
+        return SaveTGA(fileName);
+    else
+        return SavePNG(fileName);
+}
 
 bool Image::SetSize(int width, int height, unsigned components)
 {
@@ -1212,6 +1225,58 @@ bool Image::SaveJPG(const String& fileName, int quality) const
         return false;
 }
 
+bool Image::SaveDDS(const String& fileName) const
+{
+    URHO3D_PROFILE(SaveImageDDS);
+
+    File outFile(context_, fileName, FILE_WRITE);
+    if (!outFile.IsOpen())
+    {
+        URHO3D_LOGERROR("Access denied to " + fileName);
+        return false;
+    }
+
+    if (IsCompressed())
+    {
+        URHO3D_LOGERROR("Can not save compressed image to DDS");
+        return false;
+    }
+
+    if (components_ != 4)
+    {
+        URHO3D_LOGERRORF("Can not save image with %u components to DDS", components_);
+        return false;
+    }
+
+    // Write image
+    PODVector<const Image*> levels;
+    GetLevels(levels);
+
+    outFile.WriteFileID("DDS ");
+
+    DDSurfaceDesc2 ddsd;
+    memset(&ddsd, 0, sizeof(ddsd));
+    ddsd.dwSize_ = sizeof(ddsd);
+    ddsd.dwFlags_ = 0x00000001l /*DDSD_CAPS*/
+        | 0x00000002l /*DDSD_HEIGHT*/ | 0x00000004l /*DDSD_WIDTH*/ | 0x00020000l /*DDSD_MIPMAPCOUNT*/ | 0x00001000l /*DDSD_PIXELFORMAT*/;
+    ddsd.dwWidth_ = width_;
+    ddsd.dwHeight_ = height_;
+    ddsd.dwMipMapCount_ = levels.Size();
+    ddsd.ddpfPixelFormat_.dwFlags_ = 0x00000040l /*DDPF_RGB*/ | 0x00000001l /*DDPF_ALPHAPIXELS*/;
+    ddsd.ddpfPixelFormat_.dwSize_ = sizeof(ddsd.ddpfPixelFormat_);
+    ddsd.ddpfPixelFormat_.dwRGBBitCount_ = 32;
+    ddsd.ddpfPixelFormat_.dwRBitMask_ = 0x000000ff;
+    ddsd.ddpfPixelFormat_.dwGBitMask_ = 0x0000ff00;
+    ddsd.ddpfPixelFormat_.dwBBitMask_ = 0x00ff0000;
+    ddsd.ddpfPixelFormat_.dwRGBAlphaBitMask_ = 0xff000000;
+
+    outFile.Write(&ddsd, sizeof(ddsd));
+    for (unsigned i = 0; i < levels.Size(); ++i)
+        outFile.Write(levels[i]->GetData(), levels[i]->GetWidth() * levels[i]->GetHeight() * 4);
+
+    return true;
+}
+
 Color Image::GetPixel(int x, int y) const
 {
     return GetPixel(x, y, 0);

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

@@ -104,6 +104,8 @@ public:
     virtual bool BeginLoad(Deserializer& source);
     /// Save the image to a stream. Regardless of original format, the image is saved as png. Compressed image data is not supported. Return true if successful.
     virtual bool Save(Serializer& dest) const;
+    /// Save the image to a file. Format of the image is determined by file extension. JPG is saved with maximum quality.
+    virtual bool Save(const String& fileName) const;
 
     /// Set 2D size and number of color components. Old image data will be destroyed and new data is undefined. Return true if successful.
     bool SetSize(int width, int height, unsigned components);
@@ -139,6 +141,8 @@ public:
     bool SaveTGA(const String& fileName) const;
     /// Save in JPG format with compression quality. Return true if successful.
     bool SaveJPG(const String& fileName, int quality) const;
+    /// Save in DDS format. Only uncompressed RGBA images are supported. Return true if successful.
+    bool SaveDDS(const String& fileName) const;
     /// Whether this texture is detected as a cubemap, only relevant for DDS.
     bool IsCubemap() const { return cubemap_; }
     /// Whether this texture has been detected as a volume, only relevant for DDS.

+ 13 - 0
Source/Urho3D/Resource/Resource.cpp

@@ -23,6 +23,7 @@
 #include "../Precompiled.h"
 
 #include "../Core/Profiler.h"
+#include "../IO/File.h"
 #include "../IO/Log.h"
 #include "../Resource/Resource.h"
 
@@ -82,6 +83,18 @@ bool Resource::Save(Serializer& dest) const
     return false;
 }
 
+bool Resource::Load(const String& fileName)
+{
+    File file(context_);
+    return file.Open(fileName, FILE_READ) && Load(file);
+}
+
+bool Resource::Save(const String& fileName) const
+{
+    File file(context_);
+    return file.Open(fileName, FILE_WRITE) && Save(file);
+}
+
 void Resource::SetName(const String& name)
 {
     name_ = name;

+ 5 - 0
Source/Urho3D/Resource/Resource.h

@@ -64,6 +64,11 @@ public:
     /// Save resource. Return true if successful.
     virtual bool Save(Serializer& dest) const;
 
+    /// Load resource from file.
+    bool Load(const String& fileName);
+    /// Save resource to file.
+    virtual bool Save(const String& fileName) const;
+
     /// Set name.
     void SetName(const String& name);
     /// Set memory use in bytes, possibly approximate.

+ 5 - 16
Source/Urho3D/Resource/XMLElement.cpp

@@ -990,32 +990,23 @@ bool XPathResultSet::Empty() const
     return resultSet_ ? resultSet_->empty() : true;
 }
 
-XPathQuery::XPathQuery() :
-    query_(0),
-    variables_(0)
+XPathQuery::XPathQuery()
 {
 }
 
-XPathQuery::XPathQuery(const String& queryString, const String& variableString) :
-    query_(0),
-    variables_(0)
+XPathQuery::XPathQuery(const String& queryString, const String& variableString)
 {
     SetQuery(queryString, variableString);
 }
 
 XPathQuery::~XPathQuery()
 {
-    delete variables_;
-    variables_ = 0;
-    delete query_;
-    query_ = 0;
 }
 
 void XPathQuery::Bind()
 {
     // Delete previous query object and create a new one binding it with variable set
-    delete query_;
-    query_ = new pugi::xpath_query(queryString_.CString(), variables_);
+    query_ = new pugi::xpath_query(queryString_.CString(), variables_.Get());
 }
 
 bool XPathQuery::SetVariable(const String& name, bool value)
@@ -1100,10 +1091,8 @@ void XPathQuery::Clear()
 {
     queryString_.Clear();
 
-    delete variables_;
-    variables_ = 0;
-    delete query_;
-    query_ = 0;
+    variables_.Reset();
+    query_.Reset();
 }
 
 bool XPathQuery::EvaluateToBool(XMLElement element) const

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

@@ -370,18 +370,18 @@ public:
     String GetQuery() const { return queryString_; }
 
     /// Return pugixml xpath_query.
-    pugi::xpath_query* GetXPathQuery() const { return query_; }
+    pugi::xpath_query* GetXPathQuery() const { return query_.Get(); }
 
     /// Return pugixml xpath_variable_set.
-    pugi::xpath_variable_set* GetXPathVariableSet() const { return variables_; }
+    pugi::xpath_variable_set* GetXPathVariableSet() const { return variables_.Get(); }
 
 private:
     /// XPath query string.
     String queryString_;
     /// Pugixml xpath_query.
-    pugi::xpath_query* query_;
+    UniquePtr<pugi::xpath_query> query_;
     /// Pugixml xpath_variable_set.
-    pugi::xpath_variable_set* variables_;
+    UniquePtr<pugi::xpath_variable_set> variables_;
 };
 
 }

+ 1 - 4
Source/Urho3D/Resource/XMLFile.cpp

@@ -71,8 +71,6 @@ XMLFile::XMLFile(Context* context) :
 
 XMLFile::~XMLFile()
 {
-    delete document_;
-    document_ = 0;
 }
 
 void XMLFile::RegisterObject(Context* context)
@@ -116,11 +114,10 @@ bool XMLFile::BeginLoad(Deserializer& source)
         }
 
         // Patch this XMLFile and leave the original inherited XMLFile as it is
-        pugi::xml_document* patchDocument = document_;
+        UniquePtr<pugi::xml_document> patchDocument(document_.Detach());
         document_ = new pugi::xml_document();
         document_->reset(*inheritedXMLFile->document_);
         Patch(rootElem);
-        delete patchDocument;
 
         // Store resource dependencies so we know when to reload/repatch when the inherited resource changes
         cache->StoreResourceDependency(this, inherit);

+ 2 - 2
Source/Urho3D/Resource/XMLFile.h

@@ -66,7 +66,7 @@ public:
     XMLElement GetRoot(const String& name = String::EMPTY);
 
     /// Return the pugixml document.
-    pugi::xml_document* GetDocument() const { return document_; }
+    pugi::xml_document* GetDocument() const { return document_.Get(); }
 
     /// Serialize the XML content to a string.
     String ToString(const String& indentation = "\t") const;
@@ -92,7 +92,7 @@ private:
     bool CombineText(const pugi::xml_node& patch, const pugi::xml_node& original, bool prepend) const;
 
     /// Pugixml document.
-    pugi::xml_document* document_;
+    UniquePtr<pugi::xml_document> document_;
 };
 
 }

+ 0 - 2
Source/Urho3D/Scene/Node.cpp

@@ -72,8 +72,6 @@ Node::~Node()
     // Remove from the scene
     if (scene_)
         scene_->NodeRemoved(this);
-
-    delete impl_;
 }
 
 void Node::RegisterObject(Context* context)

+ 1 - 1
Source/Urho3D/Scene/Node.h

@@ -678,7 +678,7 @@ private:
     /// Node listeners.
     Vector<WeakPtr<Component> > listeners_;
     /// Pointer to implementation.
-    NodeImpl* impl_;
+    UniquePtr<NodeImpl> impl_;
 
 protected:
     /// User variables.

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

@@ -57,18 +57,12 @@ static unsigned RemapAttributeIndex(const Vector<AttributeInfo>* attributes, con
 
 Serializable::Serializable(Context* context) :
     Object(context),
-    networkState_(0),
-    instanceDefaultValues_(0),
     temporary_(false)
 {
 }
 
 Serializable::~Serializable()
 {
-    delete networkState_;
-    networkState_ = 0;
-    delete instanceDefaultValues_;
-    instanceDefaultValues_ = 0;
 }
 
 void Serializable::OnSetAttribute(const AttributeInfo& attr, const Variant& src)
@@ -669,8 +663,7 @@ void Serializable::ResetToDefault()
 
 void Serializable::RemoveInstanceDefault()
 {
-    delete instanceDefaultValues_;
-    instanceDefaultValues_ = 0;
+    instanceDefaultValues_.Reset();
 }
 
 void Serializable::SetTemporary(bool enable)

+ 3 - 3
Source/Urho3D/Scene/Serializable.h

@@ -126,11 +126,11 @@ public:
     bool GetInterceptNetworkUpdate(const String& attributeName) const;
 
     /// Return the network attribute state, if allocated.
-    NetworkState* GetNetworkState() const { return networkState_; }
+    NetworkState* GetNetworkState() const { return networkState_.Get(); }
 
 protected:
     /// Network attribute state.
-    NetworkState* networkState_;
+    UniquePtr<NetworkState> networkState_;
 
 private:
     /// Set instance-level default value. Allocate the internal data structure as necessary.
@@ -139,7 +139,7 @@ private:
     Variant GetInstanceDefault(const String& name) const;
 
     /// Attribute default value at each instance level.
-    VariantMap* instanceDefaultValues_;
+    UniquePtr<VariantMap> instanceDefaultValues_;
     /// Temporary flag.
     bool temporary_;
 };

+ 2 - 3
Source/Urho3D/UI/FontFaceBitmap.cpp

@@ -355,15 +355,14 @@ unsigned FontFaceBitmap::ConvertFormatToNumComponents(unsigned format)
 
 SharedPtr<Image> FontFaceBitmap::SaveFaceTexture(Texture2D* texture)
 {
-    Image* image = new Image(font_->GetContext());
+    SharedPtr<Image> image(new Image(font_->GetContext()));
     image->SetSize(texture->GetWidth(), texture->GetHeight(), ConvertFormatToNumComponents(texture->GetFormat()));
     if (!texture->GetData(0, image->GetData()))
     {
-        delete image;
         URHO3D_LOGERROR("Could not save texture to image resource");
         return SharedPtr<Image>();
     }
-    return SharedPtr<Image>(image);
+    return image;
 }
 
 bool FontFaceBitmap::SaveFaceTexture(Texture2D* texture, const String& fileName)

+ 1 - 6
Source/Urho3D/Urho2D/AnimatedSprite2D.cpp

@@ -59,7 +59,6 @@ AnimatedSprite2D::AnimatedSprite2D(Context* context) :
     animationStateData_(0),
     animationState_(0),
 #endif
-    spriterInstance_(0),
     speed_(1.0f),
     loopMode_(LM_DEFAULT)
 {
@@ -527,11 +526,7 @@ void AnimatedSprite2D::Dispose()
         skeleton_ = 0;
     }
 #endif
-    if (spriterInstance_)
-    {
-        delete spriterInstance_;
-        spriterInstance_ = 0;
-    }
+    spriterInstance_.Reset();
 }
 
 }

+ 1 - 1
Source/Urho3D/Urho2D/AnimatedSprite2D.h

@@ -143,7 +143,7 @@ protected:
 #endif
     
     /// Spriter instance.
-    Spriter::SpriterInstance* spriterInstance_;
+    UniquePtr<Spriter::SpriterInstance> spriterInstance_;
 };
 
 }

+ 1 - 6
Source/Urho3D/Urho2D/AnimationSet2D.cpp

@@ -110,7 +110,6 @@ AnimationSet2D::AnimationSet2D(Context* context) :
     skeletonData_(0),
     atlas_(0),
 #endif
-    spriterData_(0),
     hasSpriteSheet_(false)
 {
 }
@@ -525,11 +524,7 @@ void AnimationSet2D::Dispose()
     }
 #endif
 
-    if (spriterData_)
-    {
-        delete spriterData_;
-        spriterData_ = 0;
-    }
+    spriterData_.Reset();
 
     sprite_.Reset();
     spriteSheet_.Reset();

+ 2 - 2
Source/Urho3D/Urho2D/AnimationSet2D.h

@@ -76,7 +76,7 @@ public:
 #endif
 
     /// Return spriter data.
-    Spriter::SpriterData* GetSpriterData() const { return spriterData_; }
+    Spriter::SpriterData* GetSpriterData() const { return spriterData_.Get(); }
     /// Return spriter file sprite.
     Sprite2D* GetSpriterFileSprite(int folderId, int fileId) const;
 
@@ -109,7 +109,7 @@ private:
 #endif
     
     /// Spriter data.
-    Spriter::SpriterData* spriterData_;
+    UniquePtr<Spriter::SpriterData> spriterData_;
     /// Has sprite sheet.
     bool hasSpriteSheet_;
     /// Sprite sheet file path.

+ 0 - 4
Source/Urho3D/Urho2D/PhysicsWorld2D.cpp

@@ -47,7 +47,6 @@ static const int DEFAULT_POSITION_ITERATIONS = 3;
 
 PhysicsWorld2D::PhysicsWorld2D(Context* context) :
     Component(context),
-    world_(0),
     gravity_(DEFAULT_GRAVITY),
     velocityIterations_(DEFAULT_VELOCITY_ITERATIONS),
     positionIterations_(DEFAULT_POSITION_ITERATIONS),
@@ -72,9 +71,6 @@ PhysicsWorld2D::~PhysicsWorld2D()
     for (unsigned i = 0; i < rigidBodies_.Size(); ++i)
         if (rigidBodies_[i])
             rigidBodies_[i]->ReleaseBody();
-
-    delete world_;
-    world_ = 0;
 }
 
 void PhysicsWorld2D::RegisterObject(Context* context)

+ 2 - 2
Source/Urho3D/Urho2D/PhysicsWorld2D.h

@@ -197,7 +197,7 @@ public:
     int GetPositionIterations() const { return positionIterations_; }
 
     /// Return the Box2D physics world.
-    b2World* GetWorld() { return world_; }
+    b2World* GetWorld() { return world_.Get(); }
 
     /// Set node dirtying to be disregarded.
     void SetApplyingTransforms(bool enable) { applyingTransforms_ = enable; }
@@ -218,7 +218,7 @@ private:
     void SendEndContactEvents();
 
     /// Box2D physics world.
-    b2World* world_;
+    UniquePtr<b2World> world_;
     /// Gravity.
     Vector2 gravity_;
     /// Velocity iterations.