Browse Source

Added template Variant::Get() functions.
Added Serializable accessor attributes, for which Get & Set functions are provided instead of variable offset.
Cleaned up PhysicsWorld & RigidBody serialization code by using accessor attributes.

Lasse Öörni 14 years ago
parent
commit
b64d298336

+ 2 - 2
Bin/Data/Scripts/Ninja.as

@@ -204,7 +204,7 @@ class Ninja : GameObject
                     node.position = node.position + Vector3(0, 3, 0);
                     node.position = node.position + Vector3(0, 3, 0);
                     body.ApplyForce(Vector3(0, ninjaJumpForce, 0));
                     body.ApplyForce(Vector3(0, ninjaJumpForce, 0));
                     inAirTime = 1.0f;
                     inAirTime = 1.0f;
-                    controller.PlayExclusive("Models/Ninja_JumpNoHeight.ani", LAYER_MOVE, false,  0.2);
+                    controller.PlayExclusive("Models/Ninja_JumpNoHeight.ani", LAYER_MOVE, false,  0.1);
                     controller.SetTime("Models/Ninja_JumpNoHeight.ani", 0.0); // Always play from beginning
                     controller.SetTime("Models/Ninja_JumpNoHeight.ani", 0.0); // Always play from beginning
                     okToJump = false;
                     okToJump = false;
                 }
                 }
@@ -237,7 +237,7 @@ class Ninja : GameObject
 
 
             // Falling/jumping/sliding animation
             // Falling/jumping/sliding animation
             if (inAirTime > 0.01f)
             if (inAirTime > 0.01f)
-                controller.PlayExclusive("Models/Ninja_JumpNoHeight.ani", LAYER_MOVE, false, 0.2);
+                controller.PlayExclusive("Models/Ninja_JumpNoHeight.ani", LAYER_MOVE, false, 0.1);
         }
         }
 
 
         // Shooting
         // Shooting

+ 1 - 1
Bin/Data/Scripts/TestScene.as

@@ -133,7 +133,7 @@ void InitScene()
         object.castShadows = true;
         object.castShadows = true;
 
 
         CollisionShape@ shape = objectNode.CreateComponent("CollisionShape");
         CollisionShape@ shape = objectNode.CreateComponent("CollisionShape");
-        shape.SetConvexHull(cache.GetResource("Model", "Models/Mushroom.mdl"), 0.01, 0, Vector3(), Quaternion());
+        shape.SetTriangleMesh(cache.GetResource("Model", "Models/Mushroom.mdl"), 0, Vector3(), Quaternion());
         shape.collisionGroup = 2;
         shape.collisionGroup = 2;
         shape.collisionMask = 1;
         shape.collisionMask = 1;
     }
     }

+ 40 - 12
Engine/Core/Attribute.h

@@ -23,6 +23,7 @@
 
 
 #pragma once
 #pragma once
 
 
+#include "SharedPtr.h"
 #include "Variant.h"
 #include "Variant.h"
 
 
 /// Attribute used only for disk serialization
 /// Attribute used only for disk serialization
@@ -32,6 +33,18 @@ static const unsigned AM_NETWORK = 0x2;
 /// Attribute used for both (default)
 /// Attribute used for both (default)
 static const unsigned AM_BOTH = 0x3;
 static const unsigned AM_BOTH = 0x3;
 
 
+class Serializable;
+
+/// Internal helper class for invoking attribute accessors
+class AttributeAccessor : public RefCounted
+{
+public:
+    /// Get the attribute
+    virtual Variant Get(Serializable* ptr) { return Variant(); }
+    /// Set the attribute
+    virtual void Set(Serializable* ptr, const Variant& value) {}
+};
+
 /// Description of an automatically serializable variable
 /// Description of an automatically serializable variable
 struct AttributeInfo
 struct AttributeInfo
 {
 {
@@ -50,13 +63,25 @@ struct AttributeInfo
         type_(rhs.type_),
         type_(rhs.type_),
         name_(rhs.name_),
         name_(rhs.name_),
         offset_(rhs.offset_),
         offset_(rhs.offset_),
+        accessor_(rhs.accessor_),
         enumNames_(rhs.enumNames_),
         enumNames_(rhs.enumNames_),
         defaultValue_(rhs.defaultValue_),
         defaultValue_(rhs.defaultValue_),
         mode_(rhs.mode_)
         mode_(rhs.mode_)
     {
     {
     }
     }
     
     
-    /// Construct with parameters
+    /// Construct offset attribute
+    AttributeInfo(VariantType type, const char* name, unsigned offset, const Variant& defaultValue, unsigned mode) :
+        type_(type),
+        name_(name),
+        offset_(offset),
+        enumNames_(0),
+        defaultValue_(defaultValue),
+        mode_(mode)
+    {
+    }
+    
+   /// Construct offset enum attribute
     AttributeInfo(VariantType type, const char* name, unsigned offset, const char** enumNames, const Variant& defaultValue, unsigned mode) :
     AttributeInfo(VariantType type, const char* name, unsigned offset, const char** enumNames, const Variant& defaultValue, unsigned mode) :
         type_(type),
         type_(type),
         name_(name),
         name_(name),
@@ -67,6 +92,18 @@ struct AttributeInfo
     {
     {
     }
     }
     
     
+    /// Construct accessor attribute
+    AttributeInfo(VariantType type, const char* name, AttributeAccessor* accessor, const Variant& defaultValue, unsigned mode) :
+        type_(type),
+        name_(name),
+        offset_(0),
+        enumNames_(0),
+        accessor_(accessor),
+        defaultValue_(defaultValue),
+        mode_(mode)
+    {
+    }
+    
     /// Attribute type
     /// Attribute type
     VariantType type_;
     VariantType type_;
     /// Name
     /// Name
@@ -75,19 +112,10 @@ struct AttributeInfo
     unsigned offset_;
     unsigned offset_;
     /// Enum string names
     /// Enum string names
     const char** enumNames_;
     const char** enumNames_;
+    /// Helper object for accessor mode
+    SharedPtr<AttributeAccessor> accessor_;
     /// Default value for network replication
     /// Default value for network replication
     Variant defaultValue_;
     Variant defaultValue_;
     /// Attribute mode: whether to use for serialization, network replication, or both
     /// Attribute mode: whether to use for serialization, network replication, or both
     unsigned mode_;
     unsigned mode_;
 };
 };
-
-#define ATTRIBUTE(className, type, name, variable, defaultValue) context->RegisterAttribute<className>(AttributeInfo(type, name, offsetof(className, variable), 0, defaultValue, AM_BOTH))
-#define ATTRIBUTE_MODE(className, type, name, variable, defaultValue, mode) context->RegisterAttribute<className>(AttributeInfo(type, name, offsetof(className, variable), 0, defaultValue, mode))
-#define ENUM_ATTRIBUTE(className, name, variable, enumNames, defaultValue) context->RegisterAttribute<className>(AttributeInfo(VAR_INT, name, offsetof(className, variable), enumNames, defaultValue, AM_BOTH))
-#define ENUM_ATTRIBUTE_MODE(className, name, variable, enumNames, defaultValue, mode) context->RegisterAttribute<className>(AttributeInfo(VAR_INT, name, offsetof(className, variable), enumNames, defaultValue, mode))
-#define ID_ATTRIBUTE(className, type, name, id, defaultValue) context->RegisterAttribute<className>(AttributeInfo(type, name, id, 0, defaultValue, AM_BOTH))
-#define ID_ATTRIBUTE_MODE(className, type, name, id, defaultValue, mode) context->RegisterAttribute<className>(AttributeInfo(type, name, id, 0, defaultValue, mode))
-#define ID_ENUM_ATTRIBUTE(className, name, id, enumNames, defaultValue) context->RegisterAttribute<className>(AttributeInfo(VAR_INT, name, id, enumNames, defaultValue, AM_BOTH))
-#define ID_ENUM_ATTRIBUTE_MODE(className, name, id, enumNames, defaultValue, mode) context->RegisterAttribute<className>(AttributeInfo(VAR_INT, name, id, enumNames, defaultValue, mode))
-
-static const unsigned ID_ATTRIBUTE_BASE = 0x80000000;

+ 2 - 1
Engine/Core/Context.cpp

@@ -63,7 +63,8 @@ void Context::RegisterSubsystem(Object* object)
 
 
 void Context::RegisterAttribute(ShortStringHash objectType, const AttributeInfo& attr)
 void Context::RegisterAttribute(ShortStringHash objectType, const AttributeInfo& attr)
 {
 {
-    if (attr.type_ == VAR_NONE)
+    // None or Pointer types can not be supported
+    if ((attr.type_ == VAR_NONE) || (attr.type_ == VAR_PTR))
         return;
         return;
     
     
     attributes_[objectType].push_back(attr);
     attributes_[objectType].push_back(attr);

+ 125 - 1
Engine/Core/Variant.cpp

@@ -30,7 +30,6 @@
 #include "DebugNew.h"
 #include "DebugNew.h"
 
 
 const Variant Variant::EMPTY;
 const Variant Variant::EMPTY;
-
 const std::string Variant::emptyString;
 const std::string Variant::emptyString;
 const std::vector<unsigned char> Variant::emptyBuffer;
 const std::vector<unsigned char> Variant::emptyBuffer;
 const ResourceRef Variant::emptyResourceRef;
 const ResourceRef Variant::emptyResourceRef;
@@ -355,3 +354,128 @@ void Variant::SetType(VariantType newType)
         break;
         break;
     }
     }
 }
 }
+
+template<> int Variant::Get<int>() const
+{
+    return GetInt();
+}
+
+template<> unsigned Variant::Get<unsigned>() const
+{
+    return GetUInt();
+}
+
+template<> StringHash Variant::Get<StringHash>() const
+{
+    return GetStringHash();
+}
+
+template<> ShortStringHash Variant::Get<ShortStringHash>() const
+{
+    return GetShortStringHash();
+}
+
+template<> bool Variant::Get<bool>() const
+{
+    return GetBool();
+}
+
+template<> float Variant::Get<float>() const
+{
+    return GetFloat();
+}
+
+template<> const Vector2& Variant::Get<const Vector2&>() const
+{
+    return GetVector2();
+}
+
+template<> const Vector3& Variant::Get<const Vector3&>() const
+{
+    return GetVector3();
+}
+
+template<> const Vector4& Variant::Get<const Vector4&>() const
+{
+    return GetVector4();
+}
+
+template<> const Quaternion& Variant::Get<const Quaternion&>() const
+{
+    return GetQuaternion();
+}
+
+template<> const Color& Variant::Get<const Color&>() const
+{
+    return GetColor();
+}
+
+template<> const std::string& Variant::Get<const std::string&>() const
+{
+    return GetString();
+}
+
+template<> const std::vector<unsigned char>& Variant::Get<const std::vector<unsigned char>& >() const
+{
+    return GetBuffer();
+}
+
+template<> void* Variant::Get<void*>() const
+{
+    return GetPtr();
+}
+
+template<> const ResourceRef& Variant::Get<const ResourceRef&>() const
+{
+    return GetResourceRef();
+}
+
+template<> const ResourceRefList& Variant::Get<const ResourceRefList&>() const
+{
+    return GetResourceRefList();
+}
+
+template<> const VariantVector& Variant::Get<const VariantVector&>() const
+{
+    return GetVariantVector();
+}
+
+template<> const VariantMap& Variant::Get<const VariantMap&>() const
+{
+    return GetVariantMap();
+}
+
+template<> Vector2 Variant::Get<Vector2>() const
+{
+    return GetVector2();
+}
+
+template<> Vector3 Variant::Get<Vector3>() const
+{
+    return GetVector3();
+}
+
+template<> Vector4 Variant::Get<Vector4>() const
+{
+    return GetVector4();
+}
+
+template<> Quaternion Variant::Get<Quaternion>() const
+{
+    return GetQuaternion();
+}
+
+template<> Color Variant::Get<Color>() const
+{
+    return GetColor();
+}
+
+template<> std::string Variant::Get<std::string>() const
+{
+    return GetString();
+}
+
+template<> std::vector<unsigned char> Variant::Get<std::vector<unsigned char> >() const
+{
+    return GetBuffer();
+}

+ 44 - 109
Engine/Core/Variant.h

@@ -648,108 +648,46 @@ public:
     }
     }
     
     
     /// Test for inequality with an integer
     /// Test for inequality with an integer
-    bool operator != (int rhs) const
-    {
-        return !(*this == rhs);
-    }
-    
+    bool operator != (int rhs) const { return !(*this == rhs); }
     /// Test for inequality with an unsigned integer
     /// Test for inequality with an unsigned integer
-    bool operator != (unsigned rhs) const
-    {
-        return !(*this == rhs);
-    }
-    
+    bool operator != (unsigned rhs) const { return !(*this == rhs); }
     /// Test for inequality with a bool
     /// Test for inequality with a bool
-    bool operator != (bool rhs) const
-    {
-        return !(*this == rhs);
-    }
-    
+    bool operator != (bool rhs) const { return !(*this == rhs); }
     /// Test for inequality with a float
     /// Test for inequality with a float
-    bool operator != (float rhs) const
-    {
-        return !(*this == rhs);
-    }
-    
+    bool operator != (float rhs) const { return !(*this == rhs); }
     /// Test for inequality with a Vector2
     /// Test for inequality with a Vector2
-    bool operator != (const Vector2& rhs) const
-    {
-        return !(*this == rhs);
-    }
-    
+    bool operator != (const Vector2& rhs) const { return !(*this == rhs); }
     /// Test for inequality with a Vector3
     /// Test for inequality with a Vector3
-    bool operator != (const Vector3& rhs) const
-    {
-        return !(*this == rhs);
-    }
-    
+    bool operator != (const Vector3& rhs) const { return !(*this == rhs); }
     /// Test for inequality with an Vector4
     /// Test for inequality with an Vector4
-    bool operator != (const Vector4& rhs) const
-    {
-        return !(*this == rhs);
-    }
-    
+    bool operator != (const Vector4& rhs) const { return !(*this == rhs); }
     /// Test for inequality with a Quaternion
     /// Test for inequality with a Quaternion
-    bool operator != (const Quaternion& rhs) const
-    {
-        return !(*this == rhs);
-    }
-    
+    bool operator != (const Quaternion& rhs) const { return !(*this == rhs); }
     /// Test for inequality with a string
     /// Test for inequality with a string
-    bool operator != (const std::string& rhs) const
-    {
-        return !(*this == rhs);
-    }
-    
+    bool operator != (const std::string& rhs) const { return !(*this == rhs); }
     /// Test for inequality with a buffer
     /// Test for inequality with a buffer
-    bool operator != (const std::vector<unsigned char>& rhs) const
-    {
-        return !(*this == rhs);
-    }
-    
+    bool operator != (const std::vector<unsigned char>& rhs) const { return !(*this == rhs); }
     /// Test for inequality with a pointer
     /// Test for inequality with a pointer
-    bool operator != (void* rhs) const
-    {
-        return !(*this == rhs);
-    }
-    
+    bool operator != (void* rhs) const { return !(*this == rhs); }
     /// Test for inequality with an object reference
     /// Test for inequality with an object reference
-    bool operator != (const ResourceRef& rhs) const
-    {
-        return !(*this == rhs);
-    }
-    
+    bool operator != (const ResourceRef& rhs) const { return !(*this == rhs); }
     /// Test for inequality with an object reference list
     /// Test for inequality with an object reference list
-    bool operator != (const ResourceRefList& rhs) const
-    {
-        return !(*this == rhs);
-    }
-    
+    bool operator != (const ResourceRefList& rhs) const { return !(*this == rhs); }
     /// Test for inequality with a variant vector
     /// Test for inequality with a variant vector
-    bool operator != (const VariantVector& rhs) const
-    {
-        return !(*this == rhs);
-    }
-    
+    bool operator != (const VariantVector& rhs) const { return !(*this == rhs); }
     /// Test for inequality with a variant map
     /// Test for inequality with a variant map
-    bool operator != (const VariantMap& rhs) const
-    {
-        return !(*this == rhs);
-    }
-    
+    bool operator != (const VariantMap& rhs) const { return !(*this == rhs); }
     /// Test for inequality with a StringHash
     /// Test for inequality with a StringHash
-    bool operator != (const StringHash& rhs) const
-    {
-        return !(*this == rhs);
-    }
-    
+    bool operator != (const StringHash& rhs) const { return !(*this == rhs); }
     /// Test for inequality with a ShortStringHash
     /// Test for inequality with a ShortStringHash
-    bool operator != (const ShortStringHash& rhs) const
-    {
-        return !(*this == rhs);
-    }
+    bool operator != (const ShortStringHash& rhs) const { return !(*this == rhs); }
+    
+    /// Set from type and value strings. Pointers will be set to null, and VariantBuffer or VariantMap types are not supported
+    void FromString(const std::string& type, const std::string& value);
+    /// Set buffer type from a memory area
+    void SetBuffer(const void* data, unsigned size);
     
     
-    /// Return an integer, 0 if type mismatch
+    /// Return int or zero on type mismatch
     int GetInt() const
     int GetInt() const
     {
     {
         if (type_ != VAR_INT)
         if (type_ != VAR_INT)
@@ -757,15 +695,15 @@ public:
         return value_.int_;
         return value_.int_;
     }
     }
     
     
-    /// Return an unsigned integer, 0 if type mismatch
-    unsigned GetUInt() const
+    /// Return unsigned int or zero on type mismatch
+    int GetUInt() const
     {
     {
         if (type_ != VAR_INT)
         if (type_ != VAR_INT)
             return 0;
             return 0;
         return (unsigned)value_.int_;
         return (unsigned)value_.int_;
     }
     }
     
     
-    /// Return a StringHash, zero hash if type mismatch
+    /// Return StringHash or zero on type mismatch
     StringHash GetStringHash() const
     StringHash GetStringHash() const
     {
     {
         if (type_ != VAR_INT)
         if (type_ != VAR_INT)
@@ -773,7 +711,7 @@ public:
         return StringHash(value_.int_);
         return StringHash(value_.int_);
     }
     }
     
     
-    /// Return a ShortStringHash, zero hash if type mismatch
+    /// Return ShortStringHash or zero on type mismatch
     ShortStringHash GetShortStringHash() const
     ShortStringHash GetShortStringHash() const
     {
     {
         if (type_ != VAR_INT)
         if (type_ != VAR_INT)
@@ -781,7 +719,7 @@ public:
         return ShortStringHash(value_.int_);
         return ShortStringHash(value_.int_);
     }
     }
     
     
-    /// Return a bool, false if type mismatch
+    /// Return bool or false on type mismatch
     bool GetBool() const
     bool GetBool() const
     {
     {
         if (type_ != VAR_BOOL)
         if (type_ != VAR_BOOL)
@@ -789,7 +727,7 @@ public:
         return value_.bool_;
         return value_.bool_;
     }
     }
     
     
-    /// Return a float, 0 if type mismatch
+    /// Return float or zero on type mismatch
     float GetFloat() const
     float GetFloat() const
     {
     {
         if (type_ != VAR_FLOAT)
         if (type_ != VAR_FLOAT)
@@ -797,7 +735,7 @@ public:
         return value_.float_;
         return value_.float_;
     }
     }
     
     
-    /// Return a Vector2, zero vector if type mismatch
+    /// Return Vector2 or zero on type mismatch
     const Vector2& GetVector2() const
     const Vector2& GetVector2() const
     {
     {
         if (type_ != VAR_VECTOR2)
         if (type_ != VAR_VECTOR2)
@@ -805,7 +743,7 @@ public:
         return *reinterpret_cast<const Vector2*>(&value_);
         return *reinterpret_cast<const Vector2*>(&value_);
     }
     }
     
     
-    /// Return a Vector3, zero vector if type mismatch
+    /// Return Vector3 or zero on type mismatch
     const Vector3& GetVector3() const
     const Vector3& GetVector3() const
     {
     {
         if (type_ != VAR_VECTOR3)
         if (type_ != VAR_VECTOR3)
@@ -813,7 +751,7 @@ public:
         return *reinterpret_cast<const Vector3*>(&value_);
         return *reinterpret_cast<const Vector3*>(&value_);
     }
     }
     
     
-    /// Return a Vector4, zero vector if type mismatch
+    /// Return Vector4 or zero on type mismatch
     const Vector4& GetVector4() const
     const Vector4& GetVector4() const
     {
     {
         if (type_ != VAR_VECTOR4)
         if (type_ != VAR_VECTOR4)
@@ -821,7 +759,7 @@ public:
         return *reinterpret_cast<const Vector4*>(&value_);
         return *reinterpret_cast<const Vector4*>(&value_);
     }
     }
     
     
-    /// Return a Quaternion, identity if type mismatch
+    /// Return Quaternion or identity on type mismatch
     const Quaternion& GetQuaternion() const
     const Quaternion& GetQuaternion() const
     {
     {
         if (type_ != VAR_QUATERNION)
         if (type_ != VAR_QUATERNION)
@@ -829,7 +767,7 @@ public:
         return *reinterpret_cast<const Quaternion*>(&value_);
         return *reinterpret_cast<const Quaternion*>(&value_);
     }
     }
     
     
-    /// Return a Color, default if type mismatch
+    /// Return Color or default on type mismatch
     const Color& GetColor() const
     const Color& GetColor() const
     {
     {
         if (type_ != VAR_COLOR)
         if (type_ != VAR_COLOR)
@@ -837,7 +775,7 @@ public:
         return *reinterpret_cast<const Color*>(&value_);
         return *reinterpret_cast<const Color*>(&value_);
     }
     }
     
     
-    /// Return a string, empty if type mismatch
+    /// Return string or empty on type mismatch
     const std::string& GetString() const
     const std::string& GetString() const
     {
     {
         if (type_ != VAR_STRING)
         if (type_ != VAR_STRING)
@@ -845,7 +783,7 @@ public:
         return *reinterpret_cast<const std::string*>(value_.ptr_);
         return *reinterpret_cast<const std::string*>(value_.ptr_);
     }
     }
     
     
-    /// Return a buffer, empty if type mismatch
+    /// Return buffer or empty on type mismatch
     const std::vector<unsigned char>& GetBuffer() const
     const std::vector<unsigned char>& GetBuffer() const
     {
     {
         if (type_ != VAR_BUFFER)
         if (type_ != VAR_BUFFER)
@@ -853,7 +791,7 @@ public:
         return *reinterpret_cast<const std::vector<unsigned char>*>(value_.ptr_);
         return *reinterpret_cast<const std::vector<unsigned char>*>(value_.ptr_);
     }
     }
     
     
-    /// Return a pointer, null if type mismatch
+    /// Return pointer or null on type mismatch
     void* GetPtr() const
     void* GetPtr() const
     {
     {
         if (type_ != VAR_PTR)
         if (type_ != VAR_PTR)
@@ -861,7 +799,7 @@ public:
         return value_.ptr_;
         return value_.ptr_;
     }
     }
     
     
-    /// Return an object reference, empty if type mismatch
+    /// Return ResourceRef or empty on type mismatch
     const ResourceRef& GetResourceRef() const
     const ResourceRef& GetResourceRef() const
     {
     {
         if (type_ != VAR_RESOURCEREF)
         if (type_ != VAR_RESOURCEREF)
@@ -869,7 +807,7 @@ public:
         return *reinterpret_cast<ResourceRef*>(value_.ptr_);
         return *reinterpret_cast<ResourceRef*>(value_.ptr_);
     }
     }
     
     
-    /// Return an object reference list, empty if type mismatch
+    /// Return ResourceRefList or empty on type mismatch
     const ResourceRefList& GetResourceRefList() const
     const ResourceRefList& GetResourceRefList() const
     {
     {
         if (type_ != VAR_RESOURCEREFLIST)
         if (type_ != VAR_RESOURCEREFLIST)
@@ -877,7 +815,7 @@ public:
         return *reinterpret_cast<ResourceRefList*>(value_.ptr_);
         return *reinterpret_cast<ResourceRefList*>(value_.ptr_);
     }
     }
     
     
-    /// Return a variant vector, empty if type mismatch
+    /// Return VariantVector or empty on type mismatch
     const VariantVector& GetVariantVector() const
     const VariantVector& GetVariantVector() const
     {
     {
         if (type_ != VAR_VARIANTVECTOR)
         if (type_ != VAR_VARIANTVECTOR)
@@ -885,19 +823,16 @@ public:
         return *reinterpret_cast<VariantVector*>(value_.ptr_);
         return *reinterpret_cast<VariantVector*>(value_.ptr_);
     }
     }
     
     
-    /// Return a variant map, empty if type mismatch
+    /// Return VariantMap or empty on type mismatch
     const VariantMap& GetVariantMap() const
     const VariantMap& GetVariantMap() const
     {
     {
         if (type_ != VAR_VARIANTMAP)
         if (type_ != VAR_VARIANTMAP)
             return emptyVariantMap;
             return emptyVariantMap;
         return *reinterpret_cast<VariantMap*>(value_.ptr_);
         return *reinterpret_cast<VariantMap*>(value_.ptr_);
     }
     }
-    
-    /// Set from type and value strings. Pointers will be set to null, and VariantBuffer or VariantMap types are not supported
-    void FromString(const std::string& type, const std::string& value);
-    /// Set buffer type from a memory area
-    void SetBuffer(const void* data, unsigned size);
-    
+
+    /// Return the value, template version
+    template <typename T> T Get() const;
     /// Return type
     /// Return type
     VariantType GetType() const { return type_; }
     VariantType GetType() const { return type_; }
     /// Return type name
     /// Return type name

+ 5 - 5
Engine/Engine/PhysicsAPI.cpp

@@ -73,7 +73,7 @@ static void RegisterPhysicsWorld(asIScriptEngine* engine)
     engine->RegisterObjectMethod("PhysicsWorld", "void Update(float)", asMETHOD(PhysicsWorld, Update), asCALL_THISCALL);
     engine->RegisterObjectMethod("PhysicsWorld", "void Update(float)", asMETHOD(PhysicsWorld, Update), asCALL_THISCALL);
     engine->RegisterObjectMethod("PhysicsWorld", "Array<PhysicsRaycastResult>@ Raycast(const Ray& in, float, uint)", asFUNCTION(PhysicsWorldRaycast), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("PhysicsWorld", "Array<PhysicsRaycastResult>@ Raycast(const Ray& in, float, uint)", asFUNCTION(PhysicsWorldRaycast), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("PhysicsWorld", "void DrawDebugGeometry(bool)", asMETHOD(PhysicsWorld, DrawDebugGeometry), asCALL_THISCALL);
     engine->RegisterObjectMethod("PhysicsWorld", "void DrawDebugGeometry(bool)", asMETHOD(PhysicsWorld, DrawDebugGeometry), asCALL_THISCALL);
-    engine->RegisterObjectMethod("PhysicsWorld", "void set_gravity(const Vector3& in)", asMETHOD(PhysicsWorld, SetGravity), asCALL_THISCALL);
+    engine->RegisterObjectMethod("PhysicsWorld", "void set_gravity(Vector3)", asMETHOD(PhysicsWorld, SetGravity), asCALL_THISCALL);
     engine->RegisterObjectMethod("PhysicsWorld", "Vector3 get_gravity() const", asMETHOD(PhysicsWorld, GetGravity), asCALL_THISCALL);
     engine->RegisterObjectMethod("PhysicsWorld", "Vector3 get_gravity() const", asMETHOD(PhysicsWorld, GetGravity), asCALL_THISCALL);
     engine->RegisterObjectMethod("PhysicsWorld", "void set_fps(int)", asMETHOD(PhysicsWorld, SetFps), asCALL_THISCALL);
     engine->RegisterObjectMethod("PhysicsWorld", "void set_fps(int)", asMETHOD(PhysicsWorld, SetFps), asCALL_THISCALL);
     engine->RegisterObjectMethod("PhysicsWorld", "int get_fps() const", asMETHOD(PhysicsWorld, GetFps), asCALL_THISCALL);
     engine->RegisterObjectMethod("PhysicsWorld", "int get_fps() const", asMETHOD(PhysicsWorld, GetFps), asCALL_THISCALL);
@@ -157,11 +157,11 @@ static void RegisterRigidBody(asIScriptEngine* engine)
     engine->RegisterObjectMethod("RigidBody", "void ResetForces()", asMETHOD(RigidBody, ResetForces), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "void ResetForces()", asMETHOD(RigidBody, ResetForces), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "void set_mass(float)", asMETHOD(RigidBody, SetMass), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "void set_mass(float)", asMETHOD(RigidBody, SetMass), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "float get_mass() const", asMETHOD(RigidBody, GetMass), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "float get_mass() const", asMETHOD(RigidBody, GetMass), asCALL_THISCALL);
-    engine->RegisterObjectMethod("RigidBody", "void set_linearVelocity(const Vector3& in)", asMETHOD(RigidBody, SetLinearVelocity), asCALL_THISCALL);
+    engine->RegisterObjectMethod("RigidBody", "void set_linearVelocity(Vector3)", asMETHOD(RigidBody, SetLinearVelocity), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "Vector3 get_linearVelocity() const", asMETHOD(RigidBody, GetLinearVelocity), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "Vector3 get_linearVelocity() const", asMETHOD(RigidBody, GetLinearVelocity), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "void set_linearRestThreshold(float)", asMETHOD(RigidBody, SetLinearRestThreshold), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "void set_linearRestThreshold(float)", asMETHOD(RigidBody, SetLinearRestThreshold), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "float get_linearRestThreshold() const", asMETHOD(RigidBody, GetLinearRestThreshold), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "float get_linearRestThreshold() const", asMETHOD(RigidBody, GetLinearRestThreshold), asCALL_THISCALL);
-    engine->RegisterObjectMethod("RigidBody", "void set_angularVelocity(const Vector3& in)", asMETHOD(RigidBody, SetAngularVelocity), asCALL_THISCALL);
+    engine->RegisterObjectMethod("RigidBody", "void set_angularVelocity(Vector3)", asMETHOD(RigidBody, SetAngularVelocity), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "Vector3 get_angularVelocity() const", asMETHOD(RigidBody, GetAngularVelocity), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "Vector3 get_angularVelocity() const", asMETHOD(RigidBody, GetAngularVelocity), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "void set_angularRestThreshold(float)", asMETHOD(RigidBody, SetAngularRestThreshold), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "void set_angularRestThreshold(float)", asMETHOD(RigidBody, SetAngularRestThreshold), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "float get_angularRestThreshold() const", asMETHOD(RigidBody, GetAngularRestThreshold), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "float get_angularRestThreshold() const", asMETHOD(RigidBody, GetAngularRestThreshold), asCALL_THISCALL);
@@ -169,9 +169,9 @@ static void RegisterRigidBody(asIScriptEngine* engine)
     engine->RegisterObjectMethod("RigidBody", "float get_angularMaxVelocity() const", asMETHOD(RigidBody, GetAngularMaxVelocity), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "float get_angularMaxVelocity() const", asMETHOD(RigidBody, GetAngularMaxVelocity), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "void set_active(bool)", asMETHOD(RigidBody, SetActive), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "void set_active(bool)", asMETHOD(RigidBody, SetActive), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "bool get_active() const", asMETHOD(RigidBody, IsActive), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "bool get_active() const", asMETHOD(RigidBody, IsActive), asCALL_THISCALL);
-    engine->RegisterObjectMethod("RigidBody", "void set_position(const Vector3& in)", asMETHOD(RigidBody, SetPosition), asCALL_THISCALL);
+    engine->RegisterObjectMethod("RigidBody", "void set_position(Vector3)", asMETHOD(RigidBody, SetPosition), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "Vector3 get_position() const", asMETHOD(RigidBody, GetPosition), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "Vector3 get_position() const", asMETHOD(RigidBody, GetPosition), asCALL_THISCALL);
-    engine->RegisterObjectMethod("RigidBody", "void set_rotation(const Quaternion& in)", asMETHOD(RigidBody, SetRotation), asCALL_THISCALL);
+    engine->RegisterObjectMethod("RigidBody", "void set_rotation(Quaternion)", asMETHOD(RigidBody, SetRotation), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "Quaternion get_rotation() const", asMETHOD(RigidBody, GetRotation), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "Quaternion get_rotation() const", asMETHOD(RigidBody, GetRotation), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "void set_linearDampingThreshold(float)", asMETHOD(RigidBody, SetLinearDampingThreshold), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "void set_linearDampingThreshold(float)", asMETHOD(RigidBody, SetLinearDampingThreshold), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "float get_linearDampingThreshold() const", asMETHOD(RigidBody, GetLinearDampingThreshold), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "float get_linearDampingThreshold() const", asMETHOD(RigidBody, GetLinearDampingThreshold), asCALL_THISCALL);

+ 11 - 100
Engine/Physics/PhysicsWorld.cpp

@@ -140,105 +140,16 @@ void PhysicsWorld::RegisterObject(Context* context)
     ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Bounce Threshold", bounceThreshold_, DEFAULT_BOUNCETHRESHOLD);
     ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Bounce Threshold", bounceThreshold_, DEFAULT_BOUNCETHRESHOLD);
     ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Time Accumulator", timeAcc_, 0.0f);
     ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Time Accumulator", timeAcc_, 0.0f);
     ATTRIBUTE(PhysicsWorld, VAR_INT, "Random Seed", randomSeed_, 0);
     ATTRIBUTE(PhysicsWorld, VAR_INT, "Random Seed", randomSeed_, 0);
-    ID_ATTRIBUTE(PhysicsWorld, VAR_VECTOR3, "Gravity", ATTR_GRAVITY, Vector3::ZERO);
-    ID_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Linear Rest Threshold", ATTR_LIN_RESTTHRESHOLD, 0.01f);
-    ID_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Linear Damping Threshold", ATTR_LIN_DAMPINGTHRESHOLD, 0.01f);
-    ID_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Linear Damping Scale", ATTR_LIN_DAMPINGSCALE, 0.0f);
-    ID_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Angular Rest Threshold", ATTR_ANG_RESTTHRESHOLD, 0.01f);
-    ID_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Angular Damping Threshold", ATTR_ANG_DAMPINGTHRESHOLD, 0.01f);
-    ID_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Angular Damping Scale", ATTR_ANG_DAMPINGSCALE, 0.0f);
-    ID_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "ERP", ATTR_ERP, 0.2f);
-    ID_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "CFM", ATTR_CFM, 0.00001f);
-    ID_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Contact Surface Layer", ATTR_CONTACTSURFACELAYER, 0.0f);
-}
-
-void PhysicsWorld::OnSetAttribute(const AttributeInfo& attr, const Variant& value)
-{
-    switch (attr.offset_)
-    {
-    case ATTR_GRAVITY:
-        SetGravity(value.GetVector3());
-        break;
-        
-    case ATTR_LIN_RESTTHRESHOLD:
-        SetLinearRestThreshold(value.GetFloat());
-        break;
-        
-    case ATTR_LIN_DAMPINGTHRESHOLD:
-        SetLinearDampingThreshold(value.GetFloat());
-        break;
-        
-    case ATTR_LIN_DAMPINGSCALE:
-        SetLinearDampingScale(value.GetFloat());
-        break;
-        
-    case ATTR_ANG_RESTTHRESHOLD:
-        SetAngularRestThreshold(value.GetFloat());
-        break;
-        
-    case ATTR_ANG_DAMPINGTHRESHOLD:
-        SetAngularDampingThreshold(value.GetFloat());
-        break;
-        
-    case ATTR_ANG_DAMPINGSCALE:
-        SetAngularDampingScale(value.GetFloat());
-        break;
-        
-    case ATTR_ERP:
-        SetERP(value.GetFloat());
-        break;
-        
-    case ATTR_CFM:
-        SetCFM(value.GetFloat());
-        break;
-        
-    case ATTR_CONTACTSURFACELAYER:
-        SetContactSurfaceLayer(value.GetFloat());
-        break;
-        
-    default:
-        Serializable::OnSetAttribute(attr, value);
-        break;
-    }
-}
-
-Variant PhysicsWorld::OnGetAttribute(const AttributeInfo& attr)
-{
-    switch (attr.offset_)
-    {
-    case ATTR_GRAVITY:
-        return GetGravity();
-        
-    case ATTR_LIN_RESTTHRESHOLD:
-        return GetLinearRestThreshold();
-        
-    case ATTR_LIN_DAMPINGTHRESHOLD:
-        return GetLinearDampingThreshold();
-        
-    case ATTR_LIN_DAMPINGSCALE:
-        return GetLinearDampingScale();
-        
-    case ATTR_ANG_RESTTHRESHOLD:
-        return GetAngularRestThreshold();
-        
-    case ATTR_ANG_DAMPINGTHRESHOLD:
-        return GetAngularDampingThreshold();
-        
-    case ATTR_ANG_DAMPINGSCALE:
-        return GetAngularDampingScale();
-        
-    case ATTR_ERP:
-        return GetERP();
-        
-    case ATTR_CFM:
-        return GetCFM();
-        
-    case ATTR_CONTACTSURFACELAYER:
-        return GetContactSurfaceLayer();
-        
-    default:
-        return Serializable::OnGetAttribute(attr);
-    }
+    ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_VECTOR3, "Gravity", GetGravity, SetGravity, Vector3, Vector3::ZERO);
+    ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Linear Rest Threshold", GetLinearRestThreshold, SetLinearRestThreshold, float, 0.01f);
+    ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Linear Damping Threshold", GetLinearDampingThreshold, SetLinearDampingThreshold, float, 0.01f);
+    ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Linear Damping Scale", GetLinearDampingScale, SetLinearDampingScale, float, 0.0f);
+    ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Angular Rest Threshold", GetAngularRestThreshold, SetAngularRestThreshold, float, 0.01f);
+    ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Angular Damping Threshold", GetAngularDampingThreshold, SetAngularDampingThreshold, float, 0.01f);
+    ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Angular Damping Scale", GetAngularDampingScale, SetAngularDampingScale, float, 0.0f);
+    ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "ERP", GetERP, SetERP, float, 0.2f);
+    ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "CFM", GetCFM, SetCFM, float, 0.00001f);
+    ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Contact Surface Layer", GetContactSurfaceLayer, SetContactSurfaceLayer, float, 0.0f);
 }
 }
 
 
 void PhysicsWorld::Update(float timeStep)
 void PhysicsWorld::Update(float timeStep)
@@ -313,7 +224,7 @@ void PhysicsWorld::SetMaxContacts(unsigned num)
     contacts->resize(maxContacts_);
     contacts->resize(maxContacts_);
 }
 }
 
 
-void PhysicsWorld::SetGravity(const Vector3& gravity)
+void PhysicsWorld::SetGravity(Vector3 gravity)
 {
 {
     dWorldSetGravity(physicsWorld_, gravity.x_, gravity.y_, gravity.z_);;
     dWorldSetGravity(physicsWorld_, gravity.x_, gravity.y_, gravity.z_);;
 }
 }

+ 1 - 21
Engine/Physics/PhysicsWorld.h

@@ -100,11 +100,6 @@ public:
     /// Register object factory
     /// Register object factory
     static void RegisterObject(Context* context);
     static void RegisterObject(Context* context);
     
     
-    /// Handle attribute write access
-    virtual void OnSetAttribute(const AttributeInfo& attr, const Variant& value);
-    /// Handle attribute read access
-    virtual Variant OnGetAttribute(const AttributeInfo& attr);
-    
     /// Step the simulation forward
     /// Step the simulation forward
     void Update(float timeStep);
     void Update(float timeStep);
     /// Set simulation steps per second
     /// Set simulation steps per second
@@ -112,7 +107,7 @@ public:
     /// Set maximum contacts in one collision
     /// Set maximum contacts in one collision
     void SetMaxContacts(unsigned num);
     void SetMaxContacts(unsigned num);
     /// Set gravity
     /// Set gravity
-    void SetGravity(const Vector3& gravity);
+    void SetGravity(Vector3 gravity);
     /// Set default linear velocity deactivation threshold for new rigid bodies
     /// Set default linear velocity deactivation threshold for new rigid bodies
     void SetLinearRestThreshold(float threshold);
     void SetLinearRestThreshold(float threshold);
     /// Set default linear velocity damping threshold
     /// Set default linear velocity damping threshold
@@ -232,21 +227,6 @@ private:
     std::map<std::string, SharedPtr<TriangleMeshData> > triangleMeshCache_;
     std::map<std::string, SharedPtr<TriangleMeshData> > triangleMeshCache_;
     /// Cache for heightfield geometries
     /// Cache for heightfield geometries
     std::map<std::string, SharedPtr<HeightfieldData> > heightfieldCache_;
     std::map<std::string, SharedPtr<HeightfieldData> > heightfieldCache_;
-    
-    /// PhysicsWorld ID based attributes
-    enum PhysicsWorldIDAttributes
-    {
-        ATTR_GRAVITY = ID_ATTRIBUTE_BASE,
-        ATTR_LIN_RESTTHRESHOLD,
-        ATTR_LIN_DAMPINGTHRESHOLD,
-        ATTR_LIN_DAMPINGSCALE,
-        ATTR_ANG_RESTTHRESHOLD,
-        ATTR_ANG_DAMPINGTHRESHOLD,
-        ATTR_ANG_DAMPINGSCALE,
-        ATTR_ERP,
-        ATTR_CFM,
-        ATTR_CONTACTSURFACELAYER
-    };
 };
 };
 
 
 /// Register Physics library objects
 /// Register Physics library objects

+ 16 - 125
Engine/Physics/RigidBody.cpp

@@ -69,126 +69,18 @@ void RigidBody::RegisterObject(Context* context)
     context->RegisterFactory<RigidBody>();
     context->RegisterFactory<RigidBody>();
     
     
     ATTRIBUTE(RigidBody, VAR_FLOAT, "Mass", mass_, DEFAULT_MASS);
     ATTRIBUTE(RigidBody, VAR_FLOAT, "Mass", mass_, DEFAULT_MASS);
-    ID_ATTRIBUTE_MODE(RigidBody, VAR_VECTOR3, "Physics Position", ATTR_POSITION, Vector3::ZERO, AM_SERIALIZATION);
-    ID_ATTRIBUTE_MODE(RigidBody, VAR_QUATERNION, "Physics Rotation", ATTR_ROTATION, Quaternion::IDENTITY, AM_SERIALIZATION);
-    ID_ATTRIBUTE(RigidBody, VAR_VECTOR3, "Linear Velocity", ATTR_LIN_VELOCITY, Vector3::ZERO);
-    ID_ATTRIBUTE(RigidBody, VAR_FLOAT, "Linear Rest Threshold", ATTR_LIN_RESTTHRESHOLD, 0.01f);
-    ID_ATTRIBUTE(RigidBody, VAR_FLOAT, "Linear Damping Threshold", ATTR_LIN_DAMPINGTHRESHOLD, 0.01f);
-    ID_ATTRIBUTE(RigidBody, VAR_FLOAT, "Linear Damping Scale", ATTR_LIN_DAMPINGSCALE, 0.0f);
-    ID_ATTRIBUTE(RigidBody, VAR_VECTOR3, "Angular Velocity", ATTR_ANG_VELOCITY, Vector3::ZERO);
-    ID_ATTRIBUTE(RigidBody, VAR_FLOAT, "Angular Rest Threshold", ATTR_ANG_RESTTHRESHOLD, 0.01f);
-    ID_ATTRIBUTE(RigidBody, VAR_FLOAT, "Angular Damping Threshold", ATTR_ANG_DAMPINGTHRESHOLD, 0.01f);
-    ID_ATTRIBUTE(RigidBody, VAR_FLOAT, "Angular Damping Scale", ATTR_ANG_DAMPINGSCALE, 0.0f);
-    ID_ATTRIBUTE(RigidBody, VAR_FLOAT, "Angular Max Velocity", ATTR_ANG_MAXVELOCITY, M_INFINITY);
-    ID_ATTRIBUTE(RigidBody, VAR_BOOL, "Is Active", ATTR_ACTIVE, true);
-}
-
-void RigidBody::OnSetAttribute(const AttributeInfo& attr, const Variant& value)
-{
-    switch (attr.offset_)
-    {
-    case offsetof(RigidBody, mass_):
-        SetMass(value.GetFloat());
-        break;
-        
-    case ATTR_POSITION:
-        SetPosition(value.GetVector3());
-        break;
-        
-    case ATTR_ROTATION:
-        SetRotation(value.GetQuaternion());
-        break;
-        
-    case ATTR_LIN_VELOCITY:
-        SetLinearVelocity(value.GetVector3());
-        break;
-        
-    case ATTR_LIN_RESTTHRESHOLD:
-        SetLinearRestThreshold(value.GetFloat());
-        break;
-        
-    case ATTR_LIN_DAMPINGTHRESHOLD:
-        SetLinearDampingThreshold(value.GetFloat());
-        break;
-        
-    case ATTR_LIN_DAMPINGSCALE:
-        SetLinearDampingScale(value.GetFloat());
-        break;
-        
-    case ATTR_ANG_RESTTHRESHOLD:
-        SetAngularRestThreshold(value.GetFloat());
-        break;
-        
-    case ATTR_ANG_VELOCITY:
-        SetAngularVelocity(value.GetVector3());
-        break;
-        
-    case ATTR_ANG_DAMPINGTHRESHOLD:
-        SetAngularDampingThreshold(value.GetFloat());
-        break;
-        
-    case ATTR_ANG_DAMPINGSCALE:
-        SetAngularDampingScale(value.GetFloat());
-        break;
-        
-    case ATTR_ANG_MAXVELOCITY:
-        SetAngularMaxVelocity(value.GetFloat());
-        break;
-        
-    case ATTR_ACTIVE:
-        SetActive(value.GetBool());
-        break;
-        
-    default:
-        Serializable::OnSetAttribute(attr, value);
-        break;
-    }
-}
-
-
-Variant RigidBody::OnGetAttribute(const AttributeInfo& attr)
-{
-    switch (attr.offset_)
-    {
-    case ATTR_POSITION:
-        return GetPosition();
-        
-    case ATTR_ROTATION:
-        return GetRotation();
-        
-    case ATTR_LIN_VELOCITY:
-        return GetLinearVelocity();
-        
-    case ATTR_LIN_RESTTHRESHOLD:
-        return GetLinearRestThreshold();
-        
-    case ATTR_LIN_DAMPINGTHRESHOLD:
-        return GetLinearDampingThreshold();
-        
-    case ATTR_LIN_DAMPINGSCALE:
-        return GetLinearDampingScale();
-        
-    case ATTR_ANG_VELOCITY:
-        return GetAngularVelocity();
-        
-    case ATTR_ANG_RESTTHRESHOLD:
-        return GetAngularRestThreshold();
-        
-    case ATTR_ANG_DAMPINGTHRESHOLD:
-        return GetAngularDampingThreshold();
-        
-    case ATTR_ANG_DAMPINGSCALE:
-        return GetAngularDampingScale();
-        
-    case ATTR_ANG_MAXVELOCITY:
-        return GetAngularMaxVelocity();
-        
-    case ATTR_ACTIVE:
-        return IsActive();
-        
-    default:
-        return Serializable::OnGetAttribute(attr);
-    }
+    ACCESSOR_ATTRIBUTE_MODE(RigidBody, VAR_VECTOR3, "Physics Position", GetPosition, SetPosition, Vector3, Vector3::ZERO, AM_SERIALIZATION);
+    ACCESSOR_ATTRIBUTE_MODE(RigidBody, VAR_QUATERNION, "Physics Rotation", GetRotation, SetRotation, Quaternion, Quaternion::IDENTITY, AM_SERIALIZATION);
+    ACCESSOR_ATTRIBUTE(RigidBody, VAR_VECTOR3, "Linear Velocity", GetLinearVelocity, SetLinearVelocity, Vector3, Vector3::ZERO);
+    ACCESSOR_ATTRIBUTE(RigidBody, VAR_FLOAT, "Linear Rest Threshold", GetLinearRestThreshold, SetLinearRestThreshold, float, 0.01f);
+    ACCESSOR_ATTRIBUTE(RigidBody, VAR_FLOAT, "Linear Damping Threshold", GetLinearDampingThreshold, SetLinearDampingThreshold, float, 0.01f);
+    ACCESSOR_ATTRIBUTE(RigidBody, VAR_FLOAT, "Linear Damping Scale", GetLinearDampingScale, SetLinearDampingScale, float, 0.0f);
+    ACCESSOR_ATTRIBUTE(RigidBody, VAR_VECTOR3, "Angular Velocity", GetAngularVelocity, SetAngularVelocity, Vector3, Vector3::ZERO);
+    ACCESSOR_ATTRIBUTE(RigidBody, VAR_FLOAT, "Angular Rest Threshold", GetAngularRestThreshold, SetAngularRestThreshold, float, 0.01f);
+    ACCESSOR_ATTRIBUTE(RigidBody, VAR_FLOAT, "Angular Damping Threshold", GetAngularDampingThreshold, SetAngularDampingThreshold, float, 0.01f);
+    ACCESSOR_ATTRIBUTE(RigidBody, VAR_FLOAT, "Angular Damping Scale", GetAngularDampingScale, SetAngularDampingScale, float, 0.0f);
+    ACCESSOR_ATTRIBUTE(RigidBody, VAR_FLOAT, "Angular Max Velocity", GetAngularMaxVelocity, SetAngularMaxVelocity, float, M_INFINITY);
+    ACCESSOR_ATTRIBUTE(RigidBody, VAR_BOOL, "Is Active", IsActive, SetActive, bool, true);
 }
 }
 
 
 void RigidBody::SetMass(float mass)
 void RigidBody::SetMass(float mass)
@@ -197,7 +89,7 @@ void RigidBody::SetMass(float mass)
     UpdateMass();
     UpdateMass();
 }
 }
 
 
-void RigidBody::SetPosition(const Vector3& position)
+void RigidBody::SetPosition(Vector3 position)
 {
 {
     if (body_)
     if (body_)
     {
     {
@@ -206,7 +98,7 @@ void RigidBody::SetPosition(const Vector3& position)
     }
     }
 }
 }
 
 
-void RigidBody::SetRotation(const Quaternion& rotation)
+void RigidBody::SetRotation(Quaternion rotation)
 {
 {
     if (body_)
     if (body_)
     {
     {
@@ -226,7 +118,7 @@ void RigidBody::SetTransform(const Vector3& position, const Quaternion& rotation
     }
     }
 }
 }
 
 
-void RigidBody::SetLinearVelocity(const Vector3& velocity)
+void RigidBody::SetLinearVelocity(Vector3 velocity)
 {
 {
     if (body_)
     if (body_)
         dBodySetLinearVel(body_, velocity.x_, velocity.y_, velocity.z_);
         dBodySetLinearVel(body_, velocity.x_, velocity.y_, velocity.z_);
@@ -250,7 +142,7 @@ void RigidBody::SetLinearDampingScale(float scale)
         dBodySetLinearDamping(body_, scale);
         dBodySetLinearDamping(body_, scale);
 }
 }
 
 
-void RigidBody::SetAngularVelocity(const Vector3& velocity)
+void RigidBody::SetAngularVelocity(Vector3 velocity)
 {
 {
     if (body_)
     if (body_)
         dBodySetAngularVel(body_, velocity.x_, velocity.y_, velocity.z_);
         dBodySetAngularVel(body_, velocity.x_, velocity.y_, velocity.z_);
@@ -367,7 +259,6 @@ Vector3 RigidBody::GetLinearVelocity() const
         return Vector3::ZERO;
         return Vector3::ZERO;
 }
 }
 
 
-
 float RigidBody::GetLinearRestThreshold() const
 float RigidBody::GetLinearRestThreshold() const
 {
 {
     if (body_)
     if (body_)

+ 4 - 26
Engine/Physics/RigidBody.h

@@ -46,21 +46,16 @@ public:
     /// Register object factory
     /// Register object factory
     static void RegisterObject(Context* context);
     static void RegisterObject(Context* context);
     
     
-    /// Handle attribute write access
-    virtual void OnSetAttribute(const AttributeInfo& attr, const Variant& value);
-    /// Handle attribute read access
-    virtual Variant OnGetAttribute(const AttributeInfo& attr);
-    
     /// Set mass. Zero mass (or the lack of collision shapes) makes the body kinematic
     /// Set mass. Zero mass (or the lack of collision shapes) makes the body kinematic
     void SetMass(float mass);
     void SetMass(float mass);
     /// Set physics position
     /// Set physics position
-    void SetPosition(const Vector3& position);
+    void SetPosition(Vector3 position);
     /// Set physics rotation
     /// Set physics rotation
-    void SetRotation(const Quaternion& rotation);
+    void SetRotation(Quaternion rotation);
     /// Set physics transform
     /// Set physics transform
     void SetTransform(const Vector3& position, const Quaternion& rotation);
     void SetTransform(const Vector3& position, const Quaternion& rotation);
     /// Set linear velocity
     /// Set linear velocity
-    void SetLinearVelocity(const Vector3& velocity);
+    void SetLinearVelocity(Vector3 velocity);
     /// Set linear velocity deactivation threshold
     /// Set linear velocity deactivation threshold
     void SetLinearRestThreshold(float threshold);
     void SetLinearRestThreshold(float threshold);
     /// Set linear velocity damping threshold
     /// Set linear velocity damping threshold
@@ -68,7 +63,7 @@ public:
     /// Set linear velocity damping scale
     /// Set linear velocity damping scale
     void SetLinearDampingScale(float scale);
     void SetLinearDampingScale(float scale);
     /// Set angular velocity
     /// Set angular velocity
-    void SetAngularVelocity(const Vector3& angularVelocity);
+    void SetAngularVelocity(Vector3 angularVelocity);
     /// Set angular velocity deactivation threshold
     /// Set angular velocity deactivation threshold
     void SetAngularRestThreshold(float threshold);
     void SetAngularRestThreshold(float threshold);
     /// Set angular velocity damping threshold
     /// Set angular velocity damping threshold
@@ -150,21 +145,4 @@ private:
     Quaternion previousRotation_;
     Quaternion previousRotation_;
     /// Poststep flag
     /// Poststep flag
     bool inPostStep_;
     bool inPostStep_;
-    
-    /// RigidBody ID-based attributes
-    enum IDAttributes
-    {
-        ATTR_POSITION = ID_ATTRIBUTE_BASE,
-        ATTR_ROTATION,
-        ATTR_LIN_VELOCITY,
-        ATTR_LIN_RESTTHRESHOLD,
-        ATTR_LIN_DAMPINGTHRESHOLD,
-        ATTR_LIN_DAMPINGSCALE,
-        ATTR_ANG_VELOCITY,
-        ATTR_ANG_RESTTHRESHOLD,
-        ATTR_ANG_DAMPINGTHRESHOLD,
-        ATTR_ANG_DAMPINGSCALE,
-        ATTR_ANG_MAXVELOCITY,
-        ATTR_ACTIVE
-    };
 };
 };

+ 8 - 12
Engine/Scene/Serializable.cpp

@@ -49,9 +49,12 @@ Serializable::~Serializable()
 
 
 void Serializable::OnSetAttribute(const AttributeInfo& attr, const Variant& value)
 void Serializable::OnSetAttribute(const AttributeInfo& attr, const Variant& value)
 {
 {
-    // Check for ID-based attribute handling (negative offset); can not be supported in the base implementation
-    if (attr.offset_ >= ID_ATTRIBUTE_BASE)
+    // Check for accessor function mode
+    if (attr.accessor_)
+    {
+        attr.accessor_->Set(this, value);
         return;
         return;
+    }
     
     
     // Calculate the destination address
     // Calculate the destination address
     void* dest = reinterpret_cast<unsigned char*>(this) + attr.offset_;
     void* dest = reinterpret_cast<unsigned char*>(this) + attr.offset_;
@@ -102,10 +105,6 @@ void Serializable::OnSetAttribute(const AttributeInfo& attr, const Variant& valu
         *(reinterpret_cast<std::vector<unsigned char>*>(dest)) = value.GetBuffer();
         *(reinterpret_cast<std::vector<unsigned char>*>(dest)) = value.GetBuffer();
         break;
         break;
         
         
-    case VAR_PTR:
-        *(reinterpret_cast<void**>(dest)) = value.GetPtr();
-        break;
-        
     case VAR_RESOURCEREF:
     case VAR_RESOURCEREF:
         *(reinterpret_cast<ResourceRef*>(dest)) = value.GetResourceRef();
         *(reinterpret_cast<ResourceRef*>(dest)) = value.GetResourceRef();
         break;
         break;
@@ -126,9 +125,9 @@ void Serializable::OnSetAttribute(const AttributeInfo& attr, const Variant& valu
 
 
 Variant Serializable::OnGetAttribute(const AttributeInfo& attr)
 Variant Serializable::OnGetAttribute(const AttributeInfo& attr)
 {
 {
-    // Check for ID-based attribute handling (negative offset); can not be supported in the base implementation
-    if (attr.offset_ >= ID_ATTRIBUTE_BASE)
-        return Variant();
+    // Check for accessor function mode
+    if (attr.accessor_)
+        return attr.accessor_->Get(this);
     
     
     // Calculate the source address
     // Calculate the source address
     void* src = reinterpret_cast<unsigned char*>(this) + attr.offset_;
     void* src = reinterpret_cast<unsigned char*>(this) + attr.offset_;
@@ -169,9 +168,6 @@ Variant Serializable::OnGetAttribute(const AttributeInfo& attr)
     case VAR_BUFFER:
     case VAR_BUFFER:
         return Variant(*(reinterpret_cast<const std::vector<unsigned char>*>(src)));
         return Variant(*(reinterpret_cast<const std::vector<unsigned char>*>(src)));
         
         
-    case VAR_PTR:
-        return Variant(*(reinterpret_cast<void**>(src)));
-        
     case VAR_RESOURCEREF:
     case VAR_RESOURCEREF:
         return Variant(*(reinterpret_cast<const ResourceRef*>(src)));
         return Variant(*(reinterpret_cast<const ResourceRef*>(src)));
         
         

+ 40 - 0
Engine/Scene/Serializable.h

@@ -76,3 +76,43 @@ protected:
     /// In network replication -flag
     /// In network replication -flag
     bool inNetwork_;
     bool inNetwork_;
 };
 };
+
+
+/// Template implementation of the attribute accessor (stores function pointers of specific class)
+template <class T, typename U> class AttributeAccessorImpl : public AttributeAccessor
+{
+public:
+    typedef U (T::*GetFunctionPtr)() const;
+    typedef void (T::*SetFunctionPtr)(U);
+    
+    /// Construct with function pointers
+    AttributeAccessorImpl(GetFunctionPtr getFunction, SetFunctionPtr setFunction) :
+        getFunction_(getFunction),
+        setFunction_(setFunction)
+    {
+    }
+    
+    virtual Variant Get(Serializable* ptr)
+    {
+        T* classPtr = static_cast<T*>(ptr);
+        return Variant((classPtr->*getFunction_)());
+    }
+    
+    virtual void Set(Serializable* ptr, const Variant& value)
+    {
+        T* classPtr = static_cast<T*>(ptr);
+        (classPtr->*setFunction_)(value.Get<U>());
+    }
+    
+    /// Class-specific pointer to get function
+    GetFunctionPtr getFunction_;
+    /// Class-specific pointer to set function
+    SetFunctionPtr setFunction_;
+};
+
+#define ATTRIBUTE(className, type, name, variable, defaultValue) context->RegisterAttribute<className>(AttributeInfo(type, name, offsetof(className, variable), 0, defaultValue, AM_BOTH))
+#define ATTRIBUTE_MODE(className, type, name, variable, defaultValue, mode) context->RegisterAttribute<className>(AttributeInfo(type, name, offsetof(className, variable), 0, defaultValue, mode))
+#define ENUM_ATTRIBUTE(className, name, variable, enumNames, defaultValue) context->RegisterAttribute<className>(AttributeInfo(VAR_INT, name, offsetof(className, variable), enumNames, defaultValue, AM_BOTH))
+#define ENUM_ATTRIBUTE_MODE(className, name, variable, enumNames, defaultValue, mode) context->RegisterAttribute<className>(AttributeInfo(VAR_INT, name, offsetof(className, variable), enumNames, defaultValue, mode))
+#define ACCESSOR_ATTRIBUTE(className, type, name, getFunction, setFunction, typeName, defaultValue) context->RegisterAttribute<className>(AttributeInfo(type, name, new AttributeAccessorImpl<className, typeName>(&className::getFunction, &className::setFunction), defaultValue, AM_BOTH))
+#define ACCESSOR_ATTRIBUTE_MODE(className, type, name, getFunction, setFunction, typeName, defaultValue, mode) context->RegisterAttribute<className>(AttributeInfo(type, name, new AttributeAccessorImpl<className, typeName>(&className::getFunction, &className::setFunction), defaultValue, mode))

+ 26 - 23
Engine/Script/ScriptInstance.cpp

@@ -83,7 +83,7 @@ void ScriptInstance::RegisterObject(Context* context)
     ATTRIBUTE(ScriptInstance, VAR_INT, "Fixed Update FPS", fixedUpdateFps_, 0);
     ATTRIBUTE(ScriptInstance, VAR_INT, "Fixed Update FPS", fixedUpdateFps_, 0);
     ATTRIBUTE_MODE(ScriptInstance, VAR_FLOAT, "Time Accumulator", fixedUpdateAcc_, 0.0f, AM_SERIALIZATION);
     ATTRIBUTE_MODE(ScriptInstance, VAR_FLOAT, "Time Accumulator", fixedUpdateAcc_, 0.0f, AM_SERIALIZATION);
     ATTRIBUTE_MODE(ScriptInstance, VAR_BUFFER, "Delayed Method Calls", delayedMethodCalls_, std::vector<unsigned char>(), AM_SERIALIZATION);
     ATTRIBUTE_MODE(ScriptInstance, VAR_BUFFER, "Delayed Method Calls", delayedMethodCalls_, std::vector<unsigned char>(), AM_SERIALIZATION);
-    ID_ATTRIBUTE(ScriptInstance, VAR_BUFFER, "Script Data", ATTR_SCRIPTDATA, std::vector<unsigned char>());
+    ACCESSOR_ATTRIBUTE(ScriptInstance, VAR_BUFFER, "Script Data", GetScriptData, SetScriptData, std::vector<unsigned char>, std::vector<unsigned char>());
 }
 }
 
 
 void ScriptInstance::OnSetAttribute(const AttributeInfo& attr, const Variant& value)
 void ScriptInstance::OnSetAttribute(const AttributeInfo& attr, const Variant& value)
@@ -122,16 +122,6 @@ void ScriptInstance::OnSetAttribute(const AttributeInfo& attr, const Variant& va
         }
         }
         break;
         break;
         
         
-    case ATTR_SCRIPTDATA:
-        if ((scriptObject_) && (methods_[METHOD_LOAD]))
-        {
-            MemoryBuffer buf(value.GetBuffer());
-            VariantVector parameters;
-            parameters.push_back(Variant((void*)static_cast<Deserializer*>(&buf)));
-            scriptFile_->Execute(scriptObject_, methods_[METHOD_LOAD], parameters);
-        }
-        break;
-        
     default:
     default:
         Serializable::OnSetAttribute(attr, value);
         Serializable::OnSetAttribute(attr, value);
         break;
         break;
@@ -158,18 +148,6 @@ Variant ScriptInstance::OnGetAttribute(const AttributeInfo& attr)
             return buf.GetBuffer();
             return buf.GetBuffer();
         }
         }
         
         
-    case ATTR_SCRIPTDATA:
-        if ((!scriptObject_) || (!methods_[METHOD_SAVE]))
-            return std::vector<unsigned char>();
-        else
-        {
-            VectorBuffer buf;
-            VariantVector parameters;
-            parameters.push_back(Variant((void*)static_cast<Serializer*>(&buf)));
-            scriptFile_->Execute(scriptObject_, methods_[METHOD_SAVE], parameters);
-            return buf.GetBuffer();
-        }
-        
     default:
     default:
         return Serializable::OnGetAttribute(attr);
         return Serializable::OnGetAttribute(attr);
     }
     }
@@ -398,6 +376,31 @@ void ScriptInstance::GetSupportedMethods()
     }
     }
 }
 }
 
 
+std::vector<unsigned char> ScriptInstance::GetScriptData() const
+{
+    if ((!scriptObject_) || (!methods_[METHOD_SAVE]))
+        return std::vector<unsigned char>();
+    else
+    {
+        VectorBuffer buf;
+        VariantVector parameters;
+        parameters.push_back(Variant((void*)static_cast<Serializer*>(&buf)));
+        scriptFile_->Execute(scriptObject_, methods_[METHOD_SAVE], parameters);
+        return buf.GetBuffer();
+    }
+}
+
+void ScriptInstance::SetScriptData(std::vector<unsigned char> data)
+{
+    if ((scriptObject_) && (methods_[METHOD_LOAD]))
+    {
+        MemoryBuffer buf(data);
+        VariantVector parameters;
+        parameters.push_back(Variant((void*)static_cast<Deserializer*>(&buf)));
+        scriptFile_->Execute(scriptObject_, methods_[METHOD_LOAD], parameters);
+    }
+}
+
 void ScriptInstance::HandleSceneUpdate(StringHash eventType, VariantMap& eventData)
 void ScriptInstance::HandleSceneUpdate(StringHash eventType, VariantMap& eventData)
 {
 {
     if ((!active_) || (!scriptObject_))
     if ((!active_) || (!scriptObject_))

+ 4 - 6
Engine/Script/ScriptInstance.h

@@ -120,6 +120,10 @@ private:
     void ClearMethods();
     void ClearMethods();
     /// Check for supported methods
     /// Check for supported methods
     void GetSupportedMethods();
     void GetSupportedMethods();
+    /// Get script object's serialization data by calling a script function
+    std::vector<unsigned char> GetScriptData() const;
+    /// Set script object's serialization data by calling a script function
+    void SetScriptData(std::vector<unsigned char> data);
     /// Handle scene update event
     /// Handle scene update event
     void HandleSceneUpdate(StringHash eventType, VariantMap& eventData);
     void HandleSceneUpdate(StringHash eventType, VariantMap& eventData);
     /// Handle scene post-update event
     /// Handle scene post-update event
@@ -157,12 +161,6 @@ private:
     float fixedPostUpdateAcc_;
     float fixedPostUpdateAcc_;
     /// Delayed method calls
     /// Delayed method calls
     std::vector<DelayedMethodCall> delayedMethodCalls_;
     std::vector<DelayedMethodCall> delayedMethodCalls_;
-    
-    /// ScriptInstance ID based attributes
-    enum IDAttributes
-    {
-        ATTR_SCRIPTDATA = ID_ATTRIBUTE_BASE
-    };
 };
 };
 
 
 /// Return the Urho3D context of the active script context
 /// Return the Urho3D context of the active script context