Browse Source

Merge branch 'mixed-accessor-attribute'

aster2013 11 years ago
parent
commit
0f1ce308e9
100 changed files with 1592 additions and 1554 deletions
  1. 6 0
      Bin/Data/LuaScripts/37_UIDrag.lua
  2. 5 0
      Bin/Data/Scripts/37_UIDrag.as
  3. 0 1
      Bin/Data/Scripts/Editor.as
  4. 1 1
      Source/Engine/Audio/SoundListener.cpp
  5. 27 27
      Source/Engine/Audio/SoundSource.cpp
  6. 9 9
      Source/Engine/Audio/SoundSource.h
  7. 8 8
      Source/Engine/Audio/SoundSource3D.cpp
  8. 1 0
      Source/Engine/Core/Object.h
  9. 0 5
      Source/Engine/Core/Spline.cpp
  10. 25 0
      Source/Engine/Core/Variant.h
  11. 24 24
      Source/Engine/Graphics/AnimatedModel.cpp
  12. 3 3
      Source/Engine/Graphics/AnimatedModel.h
  13. 57 58
      Source/Engine/Graphics/AnimationController.cpp
  14. 10 10
      Source/Engine/Graphics/AnimationController.h
  15. 64 64
      Source/Engine/Graphics/BillboardSet.cpp
  16. 11 11
      Source/Engine/Graphics/BillboardSet.h
  17. 30 30
      Source/Engine/Graphics/Camera.cpp
  18. 10 10
      Source/Engine/Graphics/Camera.h
  19. 60 60
      Source/Engine/Graphics/CustomGeometry.cpp
  20. 6 6
      Source/Engine/Graphics/CustomGeometry.h
  21. 136 136
      Source/Engine/Graphics/DecalSet.cpp
  22. 15 15
      Source/Engine/Graphics/DecalSet.h
  23. 5 5
      Source/Engine/Graphics/Drawable.cpp
  24. 39 44
      Source/Engine/Graphics/Light.cpp
  25. 21 21
      Source/Engine/Graphics/Light.h
  26. 3 3
      Source/Engine/Graphics/Octree.cpp
  27. 26 26
      Source/Engine/Graphics/ParticleEmitter.cpp
  28. 3 3
      Source/Engine/Graphics/ParticleEmitter.h
  29. 1 1
      Source/Engine/Graphics/Skybox.cpp
  30. 51 51
      Source/Engine/Graphics/StaticModel.cpp
  31. 9 9
      Source/Engine/Graphics/StaticModel.h
  32. 2 2
      Source/Engine/Graphics/StaticModelGroup.cpp
  33. 48 48
      Source/Engine/Graphics/Terrain.cpp
  34. 3 3
      Source/Engine/Graphics/Terrain.h
  35. 20 20
      Source/Engine/Graphics/Zone.cpp
  36. 8 8
      Source/Engine/Graphics/Zone.h
  37. 10 10
      Source/Engine/LuaScript/LuaScriptInstance.cpp
  38. 3 3
      Source/Engine/LuaScript/LuaScriptInstance.h
  39. 1 1
      Source/Engine/LuaScript/pkgs/Physics/PhysicsWorld.pkg
  40. 7 7
      Source/Engine/LuaScript/pkgs/Physics/RigidBody.pkg
  41. 1 1
      Source/Engine/LuaScript/pkgs/Scene/Scene.pkg
  42. 2 2
      Source/Engine/LuaScript/pkgs/Urho2D/RigidBody2D.pkg
  43. 2 2
      Source/Engine/Navigation/Navigable.cpp
  44. 174 174
      Source/Engine/Navigation/NavigationMesh.cpp
  45. 8 8
      Source/Engine/Navigation/NavigationMesh.h
  46. 4 4
      Source/Engine/Navigation/OffMeshConnection.cpp
  47. 4 4
      Source/Engine/Network/NetworkPriority.cpp
  48. 16 16
      Source/Engine/Physics/CollisionShape.cpp
  49. 12 12
      Source/Engine/Physics/CollisionShape.h
  50. 12 12
      Source/Engine/Physics/Constraint.cpp
  51. 21 21
      Source/Engine/Physics/PhysicsWorld.cpp
  52. 3 3
      Source/Engine/Physics/PhysicsWorld.h
  53. 35 35
      Source/Engine/Physics/RigidBody.cpp
  54. 15 15
      Source/Engine/Physics/RigidBody.h
  55. 2 2
      Source/Engine/Scene/Animatable.cpp
  56. 1 1
      Source/Engine/Scene/Animatable.h
  57. 9 9
      Source/Engine/Scene/Node.cpp
  58. 36 36
      Source/Engine/Scene/Scene.cpp
  59. 1 1
      Source/Engine/Scene/Scene.h
  60. 61 17
      Source/Engine/Scene/Serializable.h
  61. 6 6
      Source/Engine/Scene/SplinePath.cpp
  62. 12 12
      Source/Engine/Script/PhysicsAPI.cpp
  63. 10 10
      Source/Engine/Script/ScriptInstance.cpp
  64. 11 11
      Source/Engine/Script/ScriptInstance.h
  65. 3 3
      Source/Engine/Script/Urho2DAPI.cpp
  66. 9 14
      Source/Engine/UI/BorderImage.cpp
  67. 8 8
      Source/Engine/UI/BorderImage.h
  68. 7 7
      Source/Engine/UI/Button.cpp
  69. 5 5
      Source/Engine/UI/CheckBox.cpp
  70. 10 10
      Source/Engine/UI/Cursor.cpp
  71. 8 8
      Source/Engine/UI/Cursor.h
  72. 4 4
      Source/Engine/UI/DropDownList.cpp
  73. 10 10
      Source/Engine/UI/LineEdit.cpp
  74. 17 13
      Source/Engine/UI/ListView.cpp
  75. 3 3
      Source/Engine/UI/Menu.cpp
  76. 11 11
      Source/Engine/UI/ScrollBar.cpp
  77. 12 12
      Source/Engine/UI/ScrollView.cpp
  78. 6 11
      Source/Engine/UI/Slider.cpp
  79. 39 39
      Source/Engine/UI/Sprite.cpp
  80. 7 7
      Source/Engine/UI/Sprite.h
  81. 32 32
      Source/Engine/UI/Text.cpp
  82. 1 1
      Source/Engine/UI/Text.h
  83. 65 65
      Source/Engine/UI/Text3D.cpp
  84. 10 10
      Source/Engine/UI/Text3D.h
  85. 2 2
      Source/Engine/UI/ToolTip.cpp
  86. 1 1
      Source/Engine/UI/UI.cpp
  87. 32 52
      Source/Engine/UI/UIElement.cpp
  88. 4 4
      Source/Engine/UI/View3D.cpp
  89. 13 13
      Source/Engine/UI/Window.cpp
  90. 12 17
      Source/Engine/Urho2D/AnimatedSprite2D.cpp
  91. 2 2
      Source/Engine/Urho2D/AnimatedSprite2D.h
  92. 4 4
      Source/Engine/Urho2D/CollisionBox2D.cpp
  93. 2 2
      Source/Engine/Urho2D/CollisionChain2D.cpp
  94. 3 3
      Source/Engine/Urho2D/CollisionCircle2D.cpp
  95. 3 3
      Source/Engine/Urho2D/CollisionEdge2D.cpp
  96. 1 1
      Source/Engine/Urho2D/CollisionPolygon2D.cpp
  97. 9 9
      Source/Engine/Urho2D/CollisionShape2D.cpp
  98. 2 2
      Source/Engine/Urho2D/Constraint2D.cpp
  99. 5 5
      Source/Engine/Urho2D/ConstraintDistance2D.cpp
  100. 4 4
      Source/Engine/Urho2D/ConstraintFriction2D.cpp

+ 6 - 0
Bin/Data/LuaScripts/37_UIDrag.lua

@@ -13,6 +13,12 @@ function Start()
     -- Execute base class startup
     SampleStart()
 
+    -- Set mouse visible
+    local platform = GetPlatform()
+    if platform ~= "Android" and platform ~= "iOS" then
+        input.mouseVisible = true
+    end
+
     -- Create the UI content
     CreateGUI()
     CreateInstructions()

+ 5 - 0
Bin/Data/Scripts/37_UIDrag.as

@@ -14,6 +14,11 @@ void Start()
     // Execute base class startup
     SampleStart();
 
+    // Set mouse visible
+    String platform = GetPlatform();
+    if (platform != "Android" and platform != "iOS")
+        input.mouseVisible = true;
+    
     // Create the UI content
     CreateGUI();
     CreateInstructions();

+ 0 - 1
Bin/Data/Scripts/Editor.as

@@ -140,7 +140,6 @@ void LoadConfig()
         if (cameraElem.HasAttribute("limitrotation")) limitRotation = cameraElem.GetBool("limitrotation");
         if (cameraElem.HasAttribute("mousewheelcameraposition")) mouseWheelCameraPosition = cameraElem.GetBool("mousewheelcameraposition");
         if (cameraElem.HasAttribute("viewportmode")) viewportMode = cameraElem.GetUInt("viewportmode");
-        UpdateViewParameters();
         if (cameraElem.HasAttribute("mouseorbitmode")) mouseOrbitMode = cameraElem.GetInt("mouseorbitmode");
         UpdateViewParameters();
     }

+ 1 - 1
Source/Engine/Audio/SoundListener.cpp

@@ -44,7 +44,7 @@ void SoundListener::RegisterObject(Context* context)
 {
     context->RegisterFactory<SoundListener>(AUDIO_CATEGORY);
 
-    ACCESSOR_ATTRIBUTE(SoundListener, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
 }
 
 }

+ 27 - 27
Source/Engine/Audio/SoundSource.cpp

@@ -136,23 +136,23 @@ void SoundSource::RegisterObject(Context* context)
 {
     context->RegisterFactory<SoundSource>(AUDIO_CATEGORY);
 
-    ACCESSOR_ATTRIBUTE(SoundSource, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(SoundSource, VAR_RESOURCEREF, "Sound", GetSoundAttr, SetSoundAttr, ResourceRef, ResourceRef(Sound::GetTypeStatic()), AM_DEFAULT);
-    ENUM_ATTRIBUTE(SoundSource, "Sound Type", soundType_, typeNames, SOUND_EFFECT, AM_DEFAULT);
-    ATTRIBUTE(SoundSource, VAR_FLOAT, "Frequency", frequency_, 0.0f, AM_DEFAULT);
-    ATTRIBUTE(SoundSource, VAR_FLOAT, "Gain", gain_, 1.0f, AM_DEFAULT);
-    ATTRIBUTE(SoundSource, VAR_FLOAT, "Attenuation", attenuation_, 1.0f, AM_DEFAULT);
-    ATTRIBUTE(SoundSource, VAR_FLOAT, "Panning", panning_, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(SoundSource, VAR_BOOL, "Is Playing", IsPlaying, SetPlayingAttr, bool, false, AM_DEFAULT);
-    ATTRIBUTE(SoundSource, VAR_BOOL, "Autoremove on Stop", autoRemove_, false, AM_FILE);
-    ACCESSOR_ATTRIBUTE(SoundSource, VAR_INT, "Play Position", GetPositionAttr, SetPositionAttr, int, 0, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Sound", GetSoundAttr, SetSoundAttr, ResourceRef, ResourceRef(Sound::GetTypeStatic()), AM_DEFAULT);
+    ENUM_ATTRIBUTE("Sound Type", soundType_, typeNames, SOUND_EFFECT, AM_DEFAULT);
+    ATTRIBUTE("Frequency", float, frequency_, 0.0f, AM_DEFAULT);
+    ATTRIBUTE("Gain", float, gain_, 1.0f, AM_DEFAULT);
+    ATTRIBUTE("Attenuation", float, attenuation_, 1.0f, AM_DEFAULT);
+    ATTRIBUTE("Panning", float, panning_, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Is Playing", IsPlaying, SetPlayingAttr, bool, false, AM_DEFAULT);
+    ATTRIBUTE("Autoremove on Stop", bool, autoRemove_, false, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Play Position", GetPositionAttr, SetPositionAttr, int, 0, AM_FILE);
 }
 
 void SoundSource::Play(Sound* sound)
 {
     if (!audio_)
         return;
-    
+
     // If no frequency set yet, set from the sound's default
     if (frequency_ == 0.0f && sound)
         SetFrequency(sound->GetFrequency());
@@ -200,7 +200,7 @@ void SoundSource::Play(SoundStream* stream)
         SetFrequency(stream->GetFrequency());
 
     SharedPtr<SoundStream> streamPtr(stream);
-    
+
     // If sound source is currently playing, have to lock the audio mutex. When stream playback is explicitly
     // requested, clear the existing sound if any
     if (position_)
@@ -214,7 +214,7 @@ void SoundSource::Play(SoundStream* stream)
         sound_.Reset();
         PlayLockless(streamPtr);
     }
-    
+
     // Stream playback is not supported for network replication, no need to mark network dirty
 }
 
@@ -231,7 +231,7 @@ void SoundSource::Stop()
     }
     else
         StopLockless();
-    
+
     MarkNetworkUpdate();
 }
 
@@ -323,9 +323,9 @@ void SoundSource::Mix(int* dest, unsigned samples, int mixRate, bool stereo, boo
 {
     if (!position_ || (!sound_ && !soundStream_) || !IsEnabledEffective())
         return;
-    
+
     int streamFilledSize, outBytes;
-    
+
     if (soundStream_ && streamBuffer_)
     {
         int streamBufferSize = streamBuffer_->GetDataSize();
@@ -336,10 +336,10 @@ void SoundSource::Mix(int* dest, unsigned samples, int mixRate, bool stereo, boo
         neededSize *= soundStream_->GetSampleSize();
         neededSize -= unusedStreamSize_;
         neededSize = Clamp(neededSize, 0, streamBufferSize - unusedStreamSize_);
-        
+
         // Always start play position at the beginning of the stream buffer
         position_ = streamBuffer_->GetStart();
-        
+
         // Request new data from the stream
         signed char* dest = streamBuffer_->GetStart() + unusedStreamSize_;
         outBytes = neededSize ? soundStream_->GetData(dest, neededSize) : 0;
@@ -347,7 +347,7 @@ void SoundSource::Mix(int* dest, unsigned samples, int mixRate, bool stereo, boo
         // Zero-fill rest if stream did not produce enough data
         if (outBytes < neededSize)
             memset(dest, 0, neededSize - outBytes);
-        
+
         // Calculate amount of total bytes of data in stream buffer now, to know how much went unused after mixing
         streamFilledSize = neededSize + unusedStreamSize_;
     }
@@ -397,11 +397,11 @@ void SoundSource::Mix(int* dest, unsigned samples, int mixRate, bool stereo, boo
     if (soundStream_)
     {
         timePosition_ += ((float)samples / (float)mixRate) * frequency_ / soundStream_->GetFrequency();
-        
+
         unusedStreamSize_ = Max(streamFilledSize - (int)(size_t)(position_ - streamBuffer_->GetStart()), 0);
         if (unusedStreamSize_)
             memcpy(streamBuffer_->GetStart(), (const void*)position_, unusedStreamSize_);
-        
+
         // If stream did not produce any data, stop if applicable
         if (!outBytes && soundStream_->GetStopAtEnd())
         {
@@ -413,7 +413,7 @@ void SoundSource::Mix(int* dest, unsigned samples, int mixRate, bool stereo, boo
         timePosition_ = ((float)(int)(size_t)(position_ - sound_->GetStart())) / (sound_->GetSampleSize() * sound_->GetFrequency());
 }
 
-void SoundSource::SetSoundAttr(ResourceRef value)
+void SoundSource::SetSoundAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     Sound* newSound = cache->GetResource<Sound>(value.name_);
@@ -488,7 +488,7 @@ void SoundSource::PlayLockless(Sound* sound)
             return;
         }
     }
-    
+
     // If sound pointer is null or if sound has no data, stop playback
     StopLockless();
     sound_.Reset();
@@ -504,19 +504,19 @@ void SoundSource::PlayLockless(SharedPtr<SoundStream> stream)
         // Setup the stream buffer
         unsigned sampleSize = stream->GetSampleSize();
         unsigned streamBufferSize = sampleSize * stream->GetIntFrequency() * STREAM_BUFFER_LENGTH / 1000;
-        
+
         streamBuffer_ = new Sound(context_);
         streamBuffer_->SetSize(streamBufferSize);
         streamBuffer_->SetFormat(stream->GetIntFrequency(), stream->IsSixteenBit(), stream->IsStereo());
         streamBuffer_->SetLooped(true);
-        
+
         soundStream_ = stream;
         unusedStreamSize_ = 0;
         position_ = streamBuffer_->GetStart();
         fractPosition_ = 0;
         return;
     }
-    
+
     // If stream pointer is null, stop playback
     StopLockless();
 }
@@ -525,7 +525,7 @@ void SoundSource::StopLockless()
 {
     position_ = 0;
     timePosition_ = 0.0f;
-    
+
     // Free the sound stream and decode buffer if a stream was playing
     soundStream_.Reset();
     streamBuffer_.Reset();

+ 9 - 9
Source/Engine/Audio/SoundSource.h

@@ -39,7 +39,7 @@ static const int STREAM_BUFFER_LENGTH = 100;
 class URHO3D_API SoundSource : public Component
 {
     OBJECT(SoundSource);
-    
+
 public:
     /// Construct.
     SoundSource(Context* context);
@@ -47,7 +47,7 @@ public:
     virtual ~SoundSource();
     /// Register object factory.
     static void RegisterObject(Context* context);
-    
+
     /// Play a sound.
     void Play(Sound* sound);
     /// Play a sound with specified frequency.
@@ -74,7 +74,7 @@ public:
     void SetAutoRemove(bool enable);
     /// Set new playback position.
     void SetPlayPosition(signed char* pos);
-    
+
     /// Return sound.
     Sound* GetSound() const { return sound_; }
     /// Return playback position.
@@ -95,14 +95,14 @@ public:
     bool GetAutoRemove() const { return autoRemove_; }
     /// Return whether is playing.
     bool IsPlaying() const;
-    
+
     /// Update the sound source. Perform subclass specific operations. Called by Audio.
     virtual void Update(float timeStep);
     /// Mix sound source output to a 32-bit clipping buffer. Called by Audio.
     void Mix(int* dest, unsigned samples, int mixRate, bool stereo, bool interpolation);
-    
+
     /// Set sound attribute.
-    void SetSoundAttr(ResourceRef value);
+    void SetSoundAttr(const ResourceRef& value);
     /// Set sound position attribute.
     void SetPositionAttr(int value);
     /// Return sound attribute.
@@ -111,7 +111,7 @@ public:
     void SetPlayingAttr(bool value);
     /// Return sound position attribute.
     int GetPositionAttr() const;
-    
+
 protected:
     /// Audio subsystem.
     WeakPtr<Audio> audio_;
@@ -129,7 +129,7 @@ protected:
     float autoRemoveTimer_;
     /// Autoremove flag.
     bool autoRemove_;
-    
+
 private:
     /// Play a sound without locking the audio mutex. Called internally.
     void PlayLockless(Sound* sound);
@@ -159,7 +159,7 @@ private:
     void MixZeroVolume(Sound* sound, unsigned samples, int mixRate);
     /// Advance playback pointer to simulate audio playback in headless mode.
     void MixNull(float timeStep);
-    
+
     /// Sound that is being played.
     SharedPtr<Sound> sound_;
     /// Sound stream that is being played.

+ 8 - 8
Source/Engine/Audio/SoundSource3D.cpp

@@ -117,15 +117,15 @@ void SoundSource3D::RegisterObject(Context* context)
 {
     context->RegisterFactory<SoundSource3D>(AUDIO_CATEGORY);
 
-    COPY_BASE_ATTRIBUTES(SoundSource3D, SoundSource);
+    COPY_BASE_ATTRIBUTES(SoundSource);
     // Remove Attenuation and Panning as attribute as they are constantly being updated
-    REMOVE_ATTRIBUTE(SoundSource3D, "Attenuation");
-    REMOVE_ATTRIBUTE(SoundSource3D, "Panning");
-    ATTRIBUTE(SoundSource3D, VAR_FLOAT, "Near Distance", nearDistance_, DEFAULT_NEARDISTANCE, AM_DEFAULT);
-    ATTRIBUTE(SoundSource3D, VAR_FLOAT, "Far Distance", farDistance_, DEFAULT_FARDISTANCE, AM_DEFAULT);
-    ATTRIBUTE(SoundSource3D, VAR_FLOAT, "Inner Angle", innerAngle_, DEFAULT_ANGLE, AM_DEFAULT);
-    ATTRIBUTE(SoundSource3D, VAR_FLOAT, "Outer Angle", outerAngle_, DEFAULT_ANGLE, AM_DEFAULT);
-    ATTRIBUTE(SoundSource3D, VAR_FLOAT, "Rolloff Factor", rolloffFactor_, DEFAULT_ROLLOFF, AM_DEFAULT);
+    REMOVE_ATTRIBUTE("Attenuation");
+    REMOVE_ATTRIBUTE("Panning");
+    ATTRIBUTE("Near Distance", float, nearDistance_, DEFAULT_NEARDISTANCE, AM_DEFAULT);
+    ATTRIBUTE("Far Distance", float, farDistance_, DEFAULT_FARDISTANCE, AM_DEFAULT);
+    ATTRIBUTE("Inner Angle", float, innerAngle_, DEFAULT_ANGLE, AM_DEFAULT);
+    ATTRIBUTE("Outer Angle", float, outerAngle_, DEFAULT_ANGLE, AM_DEFAULT);
+    ATTRIBUTE("Rolloff Factor", float, rolloffFactor_, DEFAULT_ROLLOFF, AM_DEFAULT);
 }
 
 void SoundSource3D::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)

+ 1 - 0
Source/Engine/Core/Object.h

@@ -33,6 +33,7 @@ class EventHandler;
 
 #define OBJECT(typeName) \
     public: \
+        typedef typeName ClassName; \
         virtual Urho3D::StringHash GetType() const { return GetTypeStatic(); } \
         virtual Urho3D::StringHash GetBaseType() const { return GetBaseTypeStatic(); } \
         virtual const Urho3D::String& GetTypeName() const { return GetTypeNameStatic(); } \

+ 0 - 5
Source/Engine/Core/Spline.cpp

@@ -33,11 +33,6 @@ const char* interpolationModeNames[] =
     0
 };
 
-template<> InterpolationMode Variant::Get<InterpolationMode>() const
-{
-    return (InterpolationMode) GetInt();
-}
-
 Spline::Spline() :
     interpolationMode_(BEZIER_CURVE)
 {

+ 25 - 0
Source/Engine/Core/Variant.h

@@ -825,4 +825,29 @@ private:
     VariantValue value_;
 };
 
+/// Return variant type from type.
+template<typename T> VariantType GetVariantType();
+
+/// Return variant type from concrete types.
+template<> inline VariantType GetVariantType<int>() { return VAR_INT; }
+template<> inline VariantType GetVariantType<unsigned>() { return VAR_INT; }
+template<> inline VariantType GetVariantType<bool>() { return VAR_BOOL; }
+template<> inline VariantType GetVariantType<float>() { return VAR_FLOAT; }
+template<> inline VariantType GetVariantType<Vector2>() { return VAR_VECTOR2; }
+template<> inline VariantType GetVariantType<Vector3>() { return VAR_VECTOR3; }
+template<> inline VariantType GetVariantType<Vector4>() { return VAR_VECTOR4; }
+template<> inline VariantType GetVariantType<Quaternion>() { return VAR_QUATERNION; }
+template<> inline VariantType GetVariantType<Color>() { return VAR_COLOR; }
+template<> inline VariantType GetVariantType<String>() { return VAR_STRING; }
+template<> inline VariantType GetVariantType<PODVector<unsigned char> >() { return VAR_BUFFER; }
+template<> inline VariantType GetVariantType<ResourceRef>() { return VAR_RESOURCEREF; }
+template<> inline VariantType GetVariantType<ResourceRefList>() { return VAR_RESOURCEREFLIST; }
+template<> inline VariantType GetVariantType<VariantVector>() { return VAR_VARIANTVECTOR; }
+template<> inline VariantType GetVariantType<VariantMap>() { return VAR_VARIANTMAP; }
+template<> inline VariantType GetVariantType<IntRect>() { return VAR_INTRECT; }
+template<> inline VariantType GetVariantType<IntVector2>() { return VAR_INTVECTOR2; }
+template<> inline VariantType GetVariantType<Matrix3>() { return VAR_MATRIX3; }
+template<> inline VariantType GetVariantType<Matrix3x4>() { return VAR_MATRIX3X4; }
+template<> inline VariantType GetVariantType<Matrix4>() { return VAR_MATRIX4; }
+
 }

+ 24 - 24
Source/Engine/Graphics/AnimatedModel.cpp

@@ -91,21 +91,21 @@ void AnimatedModel::RegisterObject(Context* context)
 {
     context->RegisterFactory<AnimatedModel>(GEOMETRY_CATEGORY);
 
-    ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_RESOURCEREF, "Model", GetModelAttr, SetModelAttr, ResourceRef, ResourceRef(Model::GetTypeStatic()), AM_DEFAULT);
-    REF_ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_RESOURCEREFLIST, "Material", GetMaterialsAttr, SetMaterialsAttr, ResourceRefList, ResourceRefList(Material::GetTypeStatic()), AM_DEFAULT);
-    ATTRIBUTE(AnimatedModel, VAR_BOOL, "Is Occluder", occluder_, false, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_BOOL, "Can Be Occluded", IsOccludee, SetOccludee, bool, true, AM_DEFAULT);
-    ATTRIBUTE(AnimatedModel, VAR_BOOL, "Cast Shadows", castShadows_, false, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_BOOL, "Update When Invisible", GetUpdateInvisible, SetUpdateInvisible, bool, false, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_FLOAT, "Draw Distance", GetDrawDistance, SetDrawDistance, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_FLOAT, "Shadow Distance", GetShadowDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_FLOAT, "LOD Bias", GetLodBias, SetLodBias, float, 1.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_FLOAT, "Animation LOD Bias", GetAnimationLodBias, SetAnimationLodBias, float, 1.0f, AM_DEFAULT);
-    COPY_BASE_ATTRIBUTES(AnimatedModel, Drawable);
-    ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_VARIANTVECTOR, "Bone Animation Enabled", GetBonesEnabledAttr, SetBonesEnabledAttr, VariantVector, Variant::emptyVariantVector, AM_FILE | AM_NOEDIT);
-    ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_VARIANTVECTOR, "Animation States", GetAnimationStatesAttr, SetAnimationStatesAttr, VariantVector, Variant::emptyVariantVector, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_BUFFER, "Morphs", GetMorphsAttr, SetMorphsAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_DEFAULT | AM_NOEDIT);
+    ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Model", GetModelAttr, SetModelAttr, ResourceRef, ResourceRef(Model::GetTypeStatic()), AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Material", GetMaterialsAttr, SetMaterialsAttr, ResourceRefList, ResourceRefList(Material::GetTypeStatic()), AM_DEFAULT);
+    ATTRIBUTE("Is Occluder", bool, occluder_, false, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Can Be Occluded", IsOccludee, SetOccludee, bool, true, AM_DEFAULT);
+    ATTRIBUTE("Cast Shadows", bool, castShadows_, false, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Update When Invisible", GetUpdateInvisible, SetUpdateInvisible, bool, false, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Draw Distance", GetDrawDistance, SetDrawDistance, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Shadow Distance", GetShadowDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("LOD Bias", GetLodBias, SetLodBias, float, 1.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Animation LOD Bias", GetAnimationLodBias, SetAnimationLodBias, float, 1.0f, AM_DEFAULT);
+    COPY_BASE_ATTRIBUTES(Drawable);
+    MIXED_ACCESSOR_ATTRIBUTE("Bone Animation Enabled", GetBonesEnabledAttr, SetBonesEnabledAttr, VariantVector, Variant::emptyVariantVector, AM_FILE | AM_NOEDIT);
+    MIXED_ACCESSOR_ATTRIBUTE("Animation States", GetAnimationStatesAttr, SetAnimationStatesAttr, VariantVector, Variant::emptyVariantVector, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Morphs", GetMorphsAttr, SetMorphsAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_DEFAULT | AM_NOEDIT);
 }
 
 bool AnimatedModel::Load(Deserializer& source, bool setInstanceDefault)
@@ -264,7 +264,7 @@ void AnimatedModel::UpdateGeometry(const FrameInfo& frame)
 {
     if (morphsDirty_)
         UpdateMorphs();
-    
+
     if (skinningDirty_)
         UpdateSkinning();
 }
@@ -750,21 +750,21 @@ void AnimatedModel::SetSkeleton(const Skeleton& skeleton, bool createBones)
     assignBonesPending_ = !createBones;
 }
 
-void AnimatedModel::SetModelAttr(ResourceRef value)
+void AnimatedModel::SetModelAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     // When loading a scene, set model without creating the bone nodes (will be assigned later during post-load)
     SetModel(cache->GetResource<Model>(value.name_), !loading_);
 }
 
-void AnimatedModel::SetBonesEnabledAttr(VariantVector value)
+void AnimatedModel::SetBonesEnabledAttr(const VariantVector& value)
 {
     Vector<Bone>& bones = skeleton_.GetModifiableBones();
     for (unsigned i = 0; i < bones.Size() && i < value.Size(); ++i)
         bones[i].animated_ = value[i].GetBool();
 }
 
-void AnimatedModel::SetAnimationStatesAttr(VariantVector value)
+void AnimatedModel::SetAnimationStatesAttr(const VariantVector& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     RemoveAllAnimationStates();
@@ -775,7 +775,7 @@ void AnimatedModel::SetAnimationStatesAttr(VariantVector value)
         numStates = 0;
     if (numStates > MAX_ANIMATION_STATES)
         numStates = MAX_ANIMATION_STATES;
-    
+
     animationStates_.Reserve(numStates);
     while (numStates--)
     {
@@ -1145,14 +1145,14 @@ void AnimatedModel::UpdateAnimation(const FrameInfo& frame)
         skeleton_.ResetSilent();
         for (Vector<SharedPtr<AnimationState> >::Iterator i = animationStates_.Begin(); i != animationStates_.End(); ++i)
             (*i)->Apply();
-        
+
         // Skeleton reset and animations apply the node transforms "silently" to avoid repeated marking dirty. Mark dirty now
         node_->MarkDirty();
 
         // Calculate new bone bounding box
         UpdateBoneBoundingBox();
     }
-    
+
     animationDirty_ = false;
 }
 
@@ -1163,7 +1163,7 @@ void AnimatedModel::UpdateBoneBoundingBox()
         // The bone bounding box is in local space, so need the node's inverse transform
         boneBoundingBox_.defined_ = false;
         Matrix3x4 inverseNodeTransform = node_->GetWorldTransform().Inverse();
-        
+
         const Vector<Bone>& bones = skeleton_.GetBones();
         for (Vector<Bone>::ConstIterator i = bones.Begin(); i != bones.End(); ++i)
         {
@@ -1179,7 +1179,7 @@ void AnimatedModel::UpdateBoneBoundingBox()
                 boneBoundingBox_.Merge(Sphere(inverseNodeTransform * boneNode->GetWorldPosition(), i->radius_ * 0.5f));
         }
     }
-    
+
     boneBoundingBoxDirty_ = false;
     worldBoundingBoxDirty_ = true;
 }

+ 3 - 3
Source/Engine/Graphics/AnimatedModel.h

@@ -129,11 +129,11 @@ public:
     bool IsMaster() const { return isMaster_; }
 
     /// Set model attribute.
-    void SetModelAttr(ResourceRef value);
+    void SetModelAttr(const ResourceRef& value);
     /// Set bones' animation enabled attribute.
-    void SetBonesEnabledAttr(VariantVector value);
+    void SetBonesEnabledAttr(const VariantVector& value);
     /// Set animation states attribute.
-    void SetAnimationStatesAttr(VariantVector value);
+    void SetAnimationStatesAttr(const VariantVector& value);
     /// Set morphs attribute.
     void SetMorphsAttr(const PODVector<unsigned char>& value);
     /// Return model attribute.

+ 57 - 58
Source/Engine/Graphics/AnimationController.cpp

@@ -61,11 +61,11 @@ AnimationController::~AnimationController()
 void AnimationController::RegisterObject(Context* context)
 {
     context->RegisterFactory<AnimationController>(LOGIC_CATEGORY);
-    
-    ACCESSOR_ATTRIBUTE(AnimationController, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(AnimationController, VAR_VARIANTVECTOR, "Animations", GetAnimationsAttr, SetAnimationsAttr, VariantVector, Variant::emptyVariantVector, AM_FILE | AM_NOEDIT);
-    REF_ACCESSOR_ATTRIBUTE(AnimationController, VAR_BUFFER, "Network Animations", GetNetAnimationsAttr, SetNetAnimationsAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_NET | AM_LATESTDATA | AM_NOEDIT);
-    ACCESSOR_ATTRIBUTE(AnimationController, VAR_VARIANTVECTOR, "Node Animation States", GetNodeAnimationStatesAttr, SetNodeAnimationStatesAttr, VariantVector, Variant::emptyVariantVector, AM_FILE | AM_NOEDIT);
+
+    ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Animations", GetAnimationsAttr, SetAnimationsAttr, VariantVector, Variant::emptyVariantVector, AM_FILE | AM_NOEDIT);
+    ACCESSOR_ATTRIBUTE("Network Animations", GetNetAnimationsAttr, SetNetAnimationsAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_NET | AM_LATESTDATA | AM_NOEDIT);
+    MIXED_ACCESSOR_ATTRIBUTE("Node Animation States", GetNodeAnimationStatesAttr, SetNodeAnimationStatesAttr, VariantVector, Variant::emptyVariantVector, AM_FILE | AM_NOEDIT);
 }
 
 void AnimationController::OnSetEnabled()
@@ -94,17 +94,17 @@ void AnimationController::Update(float timeStep)
             // Advance the animation
             if (i->speed_ != 0.0f)
                 state->AddTime(i->speed_ * timeStep);
-            
+
             float targetWeight = i->targetWeight_;
             float fadeTime = i->fadeTime_;
-            
+
             // If non-looped animation at the end, activate autofade as applicable
             if (!state->IsLooped() && state->GetTime() >= state->GetLength() && i->autoFadeTime_ > 0.0f)
             {
                 targetWeight = 0.0f;
                 fadeTime = i->autoFadeTime_;
             }
-            
+
             // Process weight fade
             float currentWeight = state->GetWeight();
             if (currentWeight != targetWeight)
@@ -121,18 +121,18 @@ void AnimationController::Update(float timeStep)
                 else
                     state->SetWeight(targetWeight);
             }
-            
+
             // Remove if weight zero and target weight zero
             if (state->GetWeight() == 0.0f && (targetWeight == 0.0f || fadeTime == 0.0f))
                 remove = true;
         }
-        
+
         // Decrement the command time-to-live values
         if (i->setTimeTtl_ > 0.0f)
             i->setTimeTtl_ = Max(i->setTimeTtl_ - timeStep, 0.0f);
         if (i->setWeightTtl_ > 0.0f)
             i->setWeightTtl_ = Max(i->setWeightTtl_ - timeStep, 0.0f);
-        
+
         if (remove)
         {
             if (state)
@@ -143,7 +143,7 @@ void AnimationController::Update(float timeStep)
         else
             ++i;
     }
-    
+
     // Node hierarchy animations need to be applied manually
     for (Vector<SharedPtr<AnimationState> >::Iterator i = nodeAnimationStates_.Begin(); i != nodeAnimationStates_.End(); ++i)
         (*i)->Apply();
@@ -155,7 +155,7 @@ bool AnimationController::Play(const String& name, unsigned char layer, bool loo
     unsigned index;
     AnimationState* state;
     FindAnimation(name, index, state);
-    
+
     if (!state)
     {
         Animation* newAnimation = GetSubsystem<ResourceCache>()->GetResource<Animation>(name);
@@ -163,7 +163,7 @@ bool AnimationController::Play(const String& name, unsigned char layer, bool loo
         if (!state)
             return false;
     }
-    
+
     if (index == M_MAX_UNSIGNED)
     {
         AnimationControl newControl;
@@ -173,12 +173,12 @@ bool AnimationController::Play(const String& name, unsigned char layer, bool loo
         animations_.Push(newControl);
         index = animations_.Size() - 1;
     }
-    
+
     state->SetLayer(layer);
     state->SetLooped(looped);
     animations_[index].targetWeight_ = 1.0f;
     animations_[index].fadeTime_ = fadeInTime;
-    
+
     MarkNetworkUpdate();
     return true;
 }
@@ -200,7 +200,7 @@ bool AnimationController::Stop(const String& name, float fadeOutTime)
         animations_[index].fadeTime_ = fadeOutTime;
         MarkNetworkUpdate();
     }
-    
+
     return index != M_MAX_UNSIGNED || state != 0;
 }
 
@@ -217,7 +217,7 @@ void AnimationController::StopLayer(unsigned char layer, float fadeOutTime)
             needUpdate = true;
         }
     }
-    
+
     if (needUpdate)
         MarkNetworkUpdate();
 }
@@ -231,7 +231,7 @@ void AnimationController::StopAll(float fadeOutTime)
             i->targetWeight_ = 0.0f;
             i->fadeTime_ = fadeOutTime;
         }
-        
+
         MarkNetworkUpdate();
     }
 }
@@ -243,7 +243,7 @@ bool AnimationController::Fade(const String& name, float targetWeight, float fad
     FindAnimation(name, index, state);
     if (index == M_MAX_UNSIGNED)
         return false;
-    
+
     animations_[index].targetWeight_ = Clamp(targetWeight, 0.0f, 1.0f);
     animations_[index].fadeTime_ = fadeTime;
     MarkNetworkUpdate();
@@ -257,9 +257,9 @@ bool AnimationController::FadeOthers(const String& name, float targetWeight, flo
     FindAnimation(name, index, state);
     if (index == M_MAX_UNSIGNED || !state)
         return false;
-    
+
     unsigned char layer = state->GetLayer();
-    
+
     bool needUpdate = false;
     for (unsigned i = 0; i < animations_.Size(); ++i)
     {
@@ -275,7 +275,7 @@ bool AnimationController::FadeOthers(const String& name, float targetWeight, flo
             }
         }
     }
-    
+
     if (needUpdate)
         MarkNetworkUpdate();
     return true;
@@ -286,7 +286,7 @@ bool AnimationController::SetLayer(const String& name, unsigned char layer)
     AnimationState* state = GetAnimationState(name);
     if (!state)
         return false;
-    
+
     state->SetLayer(layer);
     MarkNetworkUpdate();
     return true;
@@ -298,11 +298,11 @@ bool AnimationController::SetStartBone(const String& name, const String& startBo
     AnimatedModel* model = GetComponent<AnimatedModel>();
     if (!model)
         return false;
-    
+
     AnimationState* state = model->GetAnimationState(name);
     if (!state)
         return false;
-    
+
     Bone* bone = model->GetSkeleton().GetBone(startBoneName);
     state->SetStartBone(bone);
     MarkNetworkUpdate();
@@ -316,7 +316,7 @@ bool AnimationController::SetTime(const String& name, float time)
     FindAnimation(name, index, state);
     if (index == M_MAX_UNSIGNED || !state)
         return false;
-    
+
     time = Clamp(time, 0.0f, state->GetLength());
     state->SetTime(time);
     // Prepare "set time" command for network replication
@@ -334,7 +334,7 @@ bool AnimationController::SetSpeed(const String& name, float speed)
     FindAnimation(name, index, state);
     if (index == M_MAX_UNSIGNED)
         return false;
-    
+
     animations_[index].speed_ = speed;
     MarkNetworkUpdate();
     return true;
@@ -347,7 +347,7 @@ bool AnimationController::SetWeight(const String& name, float weight)
     FindAnimation(name, index, state);
     if (index == M_MAX_UNSIGNED || !state)
         return false;
-    
+
     weight = Clamp(weight, 0.0f, 1.0f);
     state->SetWeight(weight);
     // Prepare "set weight" command for network replication
@@ -363,7 +363,7 @@ bool AnimationController::SetLooped(const String& name, bool enable)
     AnimationState* state = GetAnimationState(name);
     if (!state)
         return false;
-    
+
     state->SetLooped(enable);
     MarkNetworkUpdate();
     return true;
@@ -376,7 +376,7 @@ bool AnimationController::SetAutoFade(const String& name, float fadeOutTime)
     FindAnimation(name, index, state);
     if (index == M_MAX_UNSIGNED)
         return false;
-    
+
     animations_[index].autoFadeTime_ = Max(fadeOutTime, 0.0f);
     MarkNetworkUpdate();
     return true;
@@ -397,7 +397,7 @@ bool AnimationController::IsFadingIn(const String& name) const
     FindAnimation(name, index, state);
     if (index == M_MAX_UNSIGNED || !state)
         return false;
-    
+
     return animations_[index].fadeTime_ && animations_[index].targetWeight_ > state->GetWeight();
 }
 
@@ -408,7 +408,7 @@ bool AnimationController::IsFadingOut(const String& name) const
     FindAnimation(name, index, state);
     if (index == M_MAX_UNSIGNED || !state)
         return false;
-    
+
     return (animations_[index].fadeTime_ && animations_[index].targetWeight_ < state->GetWeight())
         || (!state->IsLooped() && state->GetTime() >= state->GetLength() && animations_[index].autoFadeTime_);
 }
@@ -498,7 +498,7 @@ AnimationState* AnimationController::GetAnimationState(StringHash nameHash) cons
     AnimatedModel* model = GetComponent<AnimatedModel>();
     if (model)
         return model->GetAnimationState(nameHash);
-    
+
     // Node hierarchy mode
     for (Vector<SharedPtr<AnimationState> >::ConstIterator i = nodeAnimationStates_.Begin(); i != nodeAnimationStates_.End(); ++i)
     {
@@ -506,11 +506,11 @@ AnimationState* AnimationController::GetAnimationState(StringHash nameHash) cons
         if (animation->GetNameHash() == nameHash || animation->GetAnimationNameHash() == nameHash)
             return *i;
     }
-    
+
     return 0;
 }
 
-void AnimationController::SetAnimationsAttr(VariantVector value)
+void AnimationController::SetAnimationsAttr(const VariantVector& value)
 {
     animations_.Clear();
     animations_.Reserve(value.Size() / 5);  // Incomplete data is discarded
@@ -531,19 +531,19 @@ void AnimationController::SetAnimationsAttr(VariantVector value)
 void AnimationController::SetNetAnimationsAttr(const PODVector<unsigned char>& value)
 {
     MemoryBuffer buf(value);
-    
+
     AnimatedModel* model = GetComponent<AnimatedModel>();
-    
+
     // Check which animations we need to remove
     HashSet<StringHash> processedAnimations;
-    
+
     unsigned numAnimations = buf.ReadVLE();
     while (numAnimations--)
     {
         String animName = buf.ReadString();
         StringHash animHash(animName);
         processedAnimations.Insert(animHash);
-        
+
         // Check if the animation state exists. If not, add new
         AnimationState* state = GetAnimationState(animHash);
         if (!state)
@@ -570,7 +570,7 @@ void AnimationController::SetNetAnimationsAttr(const PODVector<unsigned char>& v
             newControl.hash_ = animHash;
             animations_.Push(newControl);
         }
-        
+
         unsigned char ctrl = buf.ReadUByte();
         state->SetLayer(buf.ReadUByte());
         state->SetLooped((ctrl & CTRL_LOOPED) != 0);
@@ -612,7 +612,7 @@ void AnimationController::SetNetAnimationsAttr(const PODVector<unsigned char>& v
             }
         }
     }
-    
+
     // Set any extra animations to fade out
     for (Vector<AnimationControl>::Iterator i = animations_.Begin(); i != animations_.End(); ++i)
     {
@@ -624,8 +624,7 @@ void AnimationController::SetNetAnimationsAttr(const PODVector<unsigned char>& v
     }
 }
 
-
-void AnimationController::SetNodeAnimationStatesAttr(VariantVector value)
+void AnimationController::SetNodeAnimationStatesAttr(const VariantVector& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     nodeAnimationStates_.Clear();
@@ -636,7 +635,7 @@ void AnimationController::SetNodeAnimationStatesAttr(VariantVector value)
         numStates = 0;
     if (numStates > MAX_NODE_ANIMATION_STATES)
         numStates = MAX_NODE_ANIMATION_STATES;
-    
+
     nodeAnimationStates_.Reserve(numStates);
     while (numStates--)
     {
@@ -677,23 +676,23 @@ VariantVector AnimationController::GetAnimationsAttr() const
 const PODVector<unsigned char>& AnimationController::GetNetAnimationsAttr() const
 {
     attrBuffer_.Clear();
-    
+
     AnimatedModel* model = GetComponent<AnimatedModel>();
-    
+
     unsigned validAnimations = 0;
     for (Vector<AnimationControl>::ConstIterator i = animations_.Begin(); i != animations_.End(); ++i)
     {
         if (GetAnimationState(i->hash_))
             ++validAnimations;
     }
-    
+
     attrBuffer_.WriteVLE(validAnimations);
     for (Vector<AnimationControl>::ConstIterator i = animations_.Begin(); i != animations_.End(); ++i)
     {
         AnimationState* state = GetAnimationState(i->hash_);
         if (!state)
             continue;
-        
+
         unsigned char ctrl = 0;
         Bone* startBone = state->GetStartBone();
         if (state->IsLooped())
@@ -706,7 +705,7 @@ const PODVector<unsigned char>& AnimationController::GetNetAnimationsAttr() cons
             ctrl |= CTRL_SETTIME;
         if (i->setWeightTtl_ > 0.0f)
             ctrl |= CTRL_SETWEIGHT;
-        
+
         attrBuffer_.WriteString(i->name_);
         attrBuffer_.WriteUByte(ctrl);
         attrBuffer_.WriteUByte(state->GetLayer());
@@ -728,7 +727,7 @@ const PODVector<unsigned char>& AnimationController::GetNetAnimationsAttr() cons
             attrBuffer_.WriteUByte(i->setWeight_);
         }
     }
-    
+
     return attrBuffer_.GetBuffer();
 }
 
@@ -762,12 +761,12 @@ AnimationState* AnimationController::AddAnimationState(Animation* animation)
 {
     if (!animation)
         return 0;
-    
+
     // Model mode
     AnimatedModel* model = GetComponent<AnimatedModel>();
     if (model)
         return model->AddAnimationState(animation);
-    
+
     // Node hierarchy mode
     SharedPtr<AnimationState> newState(new AnimationState(node_, animation));
     nodeAnimationStates_.Push(newState);
@@ -778,7 +777,7 @@ void AnimationController::RemoveAnimationState(AnimationState* state)
 {
     if (!state)
         return;
-    
+
     // Model mode
     AnimatedModel* model = GetComponent<AnimatedModel>();
     if (model)
@@ -786,7 +785,7 @@ void AnimationController::RemoveAnimationState(AnimationState* state)
         model->RemoveAnimationState(state);
         return;
     }
-    
+
     // Node hierarchy mode
     for (Vector<SharedPtr<AnimationState> >::Iterator i = nodeAnimationStates_.Begin(); i != nodeAnimationStates_.End(); ++i)
     {
@@ -801,7 +800,7 @@ void AnimationController::RemoveAnimationState(AnimationState* state)
 void AnimationController::FindAnimation(const String& name, unsigned& index, AnimationState*& state) const
 {
     StringHash nameHash(name);
-    
+
     // Find the AnimationState
     state = GetAnimationState(nameHash);
     if (state)
@@ -809,7 +808,7 @@ void AnimationController::FindAnimation(const String& name, unsigned& index, Ani
         // Either a resource name or animation name may be specified. We store resource names, so correct the hash if necessary
         nameHash = state->GetAnimation()->GetNameHash();
     }
-    
+
     // Find the internal control structure
     index = M_MAX_UNSIGNED;
     for (unsigned i = 0; i < animations_.Size(); ++i)
@@ -825,7 +824,7 @@ void AnimationController::FindAnimation(const String& name, unsigned& index, Ani
 void AnimationController::HandleScenePostUpdate(StringHash eventType, VariantMap& eventData)
 {
     using namespace ScenePostUpdate;
-    
+
     Update(eventData[P_TIMESTEP].GetFloat());
 }
 

+ 10 - 10
Source/Engine/Graphics/AnimationController.h

@@ -89,10 +89,10 @@ public:
     virtual ~AnimationController();
     /// Register object factory.
     static void RegisterObject(Context* context);
-    
+
     /// Handle enabled/disabled state change.
     virtual void OnSetEnabled();
-    
+
     /// Update the animations. Is called from HandleScenePostUpdate().
     void Update(float timeStep);
     /// Play an animation and set full target weight. Name must be the full resource name. Return true on success.
@@ -109,7 +109,7 @@ public:
     bool Fade(const String& name, float targetWeight, float fadeTime);
     /// Fade other animations on the same layer to target weight. Return true on success.
     bool FadeOthers(const String& name, float targetWeight, float fadeTime);
-    
+
     /// Set animation blending layer priority. Return true on success.
     bool SetLayer(const String& name, unsigned char layer);
     /// Set animation start bone. Return true on success.
@@ -124,7 +124,7 @@ public:
     bool SetSpeed(const String& name, float speed);
     /// Set animation autofade on stop (non-looped animations only.) Zero time disables. Return true on success.
     bool SetAutoFade(const String& name, float fadeOutTime);
-    
+
     /// Return whether an animation is active.
     bool IsPlaying(const String& name) const;
     /// Return whether an animation is fading in.
@@ -157,24 +157,24 @@ public:
     AnimationState* GetAnimationState(const String& name) const;
     /// Find an animation state by animation name hash
     AnimationState* GetAnimationState(StringHash nameHash) const;
-    
+
     /// Set animation control structures attribute.
-    void SetAnimationsAttr(VariantVector value);
+    void SetAnimationsAttr(const VariantVector& value);
     /// Set animations attribute for network replication.
     void SetNetAnimationsAttr(const PODVector<unsigned char>& value);
     /// Set node animation states attribute.
-    void SetNodeAnimationStatesAttr(VariantVector value);
+    void SetNodeAnimationStatesAttr(const VariantVector& value);
     /// Return animation control structures attribute.
     VariantVector GetAnimationsAttr() const;
     /// Return animations attribute for network replication.
     const PODVector<unsigned char>& GetNetAnimationsAttr() const;
     /// Return node animation states attribute.
     VariantVector GetNodeAnimationStatesAttr() const;
-    
+
 protected:
     /// Handle node being assigned.
     virtual void OnNodeSet(Node* node);
-    
+
 private:
     /// Add an animation state either to AnimatedModel or as a node animation.
     AnimationState* AddAnimationState(Animation* animation);
@@ -184,7 +184,7 @@ private:
     void FindAnimation(const String& name, unsigned& index, AnimationState*& state) const;
     /// Handle scene post-update event.
     void HandleScenePostUpdate(StringHash eventType, VariantMap& eventData);
-    
+
     /// Animation control structures.
     Vector<AnimationControl> animations_;
     /// Node hierarchy mode animation states.

+ 64 - 64
Source/Engine/Graphics/BillboardSet.cpp

@@ -80,7 +80,7 @@ BillboardSet::BillboardSet(Context* context) :
 {
     geometry_->SetVertexBuffer(0, vertexBuffer_, MASK_POSITION | MASK_COLOR | MASK_TEXCOORD1 | MASK_TEXCOORD2);
     geometry_->SetIndexBuffer(indexBuffer_);
-    
+
     batches_.Resize(1);
     batches_[0].geometry_ = geometry_;
     batches_[0].geometryType_ = GEOM_BILLBOARD;
@@ -94,21 +94,21 @@ BillboardSet::~BillboardSet()
 void BillboardSet::RegisterObject(Context* context)
 {
     context->RegisterFactory<BillboardSet>(GEOMETRY_CATEGORY);
-    
-    ACCESSOR_ATTRIBUTE(BillboardSet, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(BillboardSet, VAR_RESOURCEREF, "Material", GetMaterialAttr, SetMaterialAttr, ResourceRef, ResourceRef(Material::GetTypeStatic()), AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(BillboardSet, VAR_BOOL, "Relative Position", IsRelative, SetRelative, bool, true, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(BillboardSet, VAR_BOOL, "Relative Scale", IsScaled, SetScaled, bool, true, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(BillboardSet, VAR_BOOL, "Sort By Distance", IsSorted, SetSorted, bool, false, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(BillboardSet, VAR_BOOL, "Can Be Occluded", IsOccludee, SetOccludee, bool, true, AM_DEFAULT);
-    ATTRIBUTE(BillboardSet, VAR_BOOL, "Cast Shadows", castShadows_, false, AM_DEFAULT);
-    ENUM_ATTRIBUTE(BillboardSet, "Face Camera Mode", faceCameraMode_, faceCameraModeNames, FC_ROTATE_XYZ, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(BillboardSet, VAR_FLOAT, "Draw Distance", GetDrawDistance, SetDrawDistance, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(BillboardSet, VAR_FLOAT, "Shadow Distance", GetShadowDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(BillboardSet, VAR_FLOAT, "Animation LOD Bias", GetAnimationLodBias, SetAnimationLodBias, float, 1.0f, AM_DEFAULT);
-    COPY_BASE_ATTRIBUTES(BillboardSet, Drawable);
-    ACCESSOR_ATTRIBUTE(BillboardSet, VAR_VARIANTVECTOR, "Billboards", GetBillboardsAttr, SetBillboardsAttr, VariantVector, Variant::emptyVariantVector, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(BillboardSet, VAR_BUFFER, "Network Billboards", GetNetBillboardsAttr, SetNetBillboardsAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_NET | AM_NOEDIT);
+
+    ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Material", GetMaterialAttr, SetMaterialAttr, ResourceRef, ResourceRef(Material::GetTypeStatic()), AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Relative Position", IsRelative, SetRelative, bool, true, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Relative Scale", IsScaled, SetScaled, bool, true, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Sort By Distance", IsSorted, SetSorted, bool, false, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Can Be Occluded", IsOccludee, SetOccludee, bool, true, AM_DEFAULT);
+    ATTRIBUTE("Cast Shadows", bool, castShadows_, false, AM_DEFAULT);
+    ENUM_ATTRIBUTE("Face Camera Mode", faceCameraMode_, faceCameraModeNames, FC_ROTATE_XYZ, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Draw Distance", GetDrawDistance, SetDrawDistance, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Shadow Distance", GetShadowDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Animation LOD Bias", GetAnimationLodBias, SetAnimationLodBias, float, 1.0f, AM_DEFAULT);
+    COPY_BASE_ATTRIBUTES(Drawable);
+    MIXED_ACCESSOR_ATTRIBUTE("Billboards", GetBillboardsAttr, SetBillboardsAttr, VariantVector, Variant::emptyVariantVector, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Network Billboards", GetNetBillboardsAttr, SetNetBillboardsAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_NET | AM_NOEDIT);
 }
 
 void BillboardSet::ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQueryResult>& results)
@@ -123,21 +123,21 @@ void BillboardSet::ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQue
     // Check ray hit distance to AABB before proceeding with billboard-level tests
     if (query.ray_.HitDistance(GetWorldBoundingBox()) >= query.maxDistance_)
         return;
-    
+
     const Matrix3x4& worldTransform = node_->GetWorldTransform();
     Matrix3x4 billboardTransform = relative_ ? worldTransform : Matrix3x4::IDENTITY;
     Vector3 billboardScale = scaled_ ? worldTransform.Scale() : Vector3::ONE;
-    
+
     for (unsigned i = 0; i < billboards_.Size(); ++i)
     {
         if (!billboards_[i].enabled_)
             continue;
-        
+
         // Approximate the billboards as spheres for raycasting
         float size = INV_SQRT_TWO * (billboards_[i].size_.x_ * billboardScale.x_ + billboards_[i].size_.y_ * billboardScale.y_);
         Vector3 center = billboardTransform * billboards_[i].position_;
         Sphere billboardSphere(center, size);
-        
+
         float distance = query.ray_.HitDistance(billboardSphere);
         if (distance < query.maxDistance_)
         {
@@ -173,9 +173,9 @@ void BillboardSet::UpdateBatches(const FrameInfo& frame)
             }
         }
     }
-    
+
     distance_ = frame.camera_->GetDistance(GetWorldBoundingBox().Center());
-    
+
     // Calculate scaled distance for animation LOD
     float scale = GetWorldBoundingBox().Size().DotProduct(DOT_SCALE);
     // If there are no billboards, the size becomes zero, and LOD'ed updates no longer happen. Disable LOD in that case
@@ -183,7 +183,7 @@ void BillboardSet::UpdateBatches(const FrameInfo& frame)
         lodDistance_ = frame.camera_->GetLodDistance(distance_, scale, lodBias_);
     else
         lodDistance_ = 0.0f;
-    
+
     batches_[0].distance_ = distance_;
     batches_[0].numWorldTransforms_ = 2;
     // Billboard positioning
@@ -197,7 +197,7 @@ void BillboardSet::UpdateGeometry(const FrameInfo& frame)
 {
     if (bufferSizeDirty_ || indexBuffer_->IsDataLost())
         UpdateBufferSize();
-    
+
     if (bufferDirty_ || vertexBuffer_->IsDataLost())
         UpdateVertexBuffer(frame);
 }
@@ -223,11 +223,11 @@ void BillboardSet::SetNumBillboards(unsigned num)
         num = 0;
     if (num > MAX_BILLBOARDS)
         num = MAX_BILLBOARDS;
-    
+
     unsigned oldNum = billboards_.Size();
-    
+
     billboards_.Resize(num);
-    
+
     // Set default values to new billboards
     for (unsigned i = oldNum; i < num; ++i)
     {
@@ -238,7 +238,7 @@ void BillboardSet::SetNumBillboards(unsigned num)
         billboards_[i].rotation_ = 0.0f;
         billboards_[i].enabled_ = false;
     }
-    
+
     bufferSizeDirty_ = true;
     Commit();
 }
@@ -289,18 +289,18 @@ Billboard* BillboardSet::GetBillboard(unsigned index)
     return index < billboards_.Size() ? &billboards_[index] : (Billboard*)0;
 }
 
-void BillboardSet::SetMaterialAttr(ResourceRef value)
+void BillboardSet::SetMaterialAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SetMaterial(cache->GetResource<Material>(value.name_));
 }
 
-void BillboardSet::SetBillboardsAttr(VariantVector value)
+void BillboardSet::SetBillboardsAttr(const VariantVector& value)
 {
     unsigned index = 0;
     unsigned numBillboards = index < value.Size() ? value[index++].GetUInt() : 0;
     SetNumBillboards(numBillboards);
-    
+
     for (PODVector<Billboard>::Iterator i = billboards_.Begin(); i != billboards_.End() && index < value.Size(); ++i)
     {
         i->position_ = value[index++].GetVector3();
@@ -311,7 +311,7 @@ void BillboardSet::SetBillboardsAttr(VariantVector value)
         i->rotation_ = value[index++].GetFloat();
         i->enabled_ = value[index++].GetBool();
     }
-    
+
     Commit();
 }
 
@@ -320,7 +320,7 @@ void BillboardSet::SetNetBillboardsAttr(const PODVector<unsigned char>& value)
     MemoryBuffer buf(value);
     unsigned numBillboards = buf.ReadVLE();
     SetNumBillboards(numBillboards);
-    
+
     for (PODVector<Billboard>::Iterator i = billboards_.Begin(); i != billboards_.End(); ++i)
     {
         i->position_ = buf.ReadVector3();
@@ -330,7 +330,7 @@ void BillboardSet::SetNetBillboardsAttr(const PODVector<unsigned char>& value)
         i->rotation_ = buf.ReadFloat();
         i->enabled_ = buf.ReadBool();
     }
-    
+
     Commit();
 }
 
@@ -344,7 +344,7 @@ VariantVector BillboardSet::GetBillboardsAttr() const
     VariantVector ret;
     ret.Reserve(billboards_.Size() * 6 + 1);
     ret.Push(billboards_.Size());
-    
+
     for (PODVector<Billboard>::ConstIterator i = billboards_.Begin(); i != billboards_.End(); ++i)
     {
         ret.Push(i->position_);
@@ -354,7 +354,7 @@ VariantVector BillboardSet::GetBillboardsAttr() const
         ret.Push(i->rotation_);
         ret.Push(i->enabled_);
     }
-    
+
     return ret;
 }
 
@@ -362,7 +362,7 @@ const PODVector<unsigned char>& BillboardSet::GetNetBillboardsAttr() const
 {
     attrBuffer_.Clear();
     attrBuffer_.WriteVLE(billboards_.Size());
-    
+
     for (PODVector<Billboard>::ConstIterator i = billboards_.Begin(); i != billboards_.End(); ++i)
     {
         attrBuffer_.WriteVector3(i->position_);
@@ -372,7 +372,7 @@ const PODVector<unsigned char>& BillboardSet::GetNetBillboardsAttr() const
         attrBuffer_.WriteFloat(i->rotation_);
         attrBuffer_.WriteBool(i->enabled_);
     }
-    
+
     return attrBuffer_.GetBuffer();
 }
 
@@ -388,15 +388,15 @@ void BillboardSet::OnWorldBoundingBoxUpdate()
     {
         if (!billboards_[i].enabled_)
             continue;
-        
+
         float size = INV_SQRT_TWO * (billboards_[i].size_.x_ * billboardScale.x_ + billboards_[i].size_.y_ * billboardScale.y_);
         Vector3 center = billboardTransform * billboards_[i].position_;
         Vector3 edge = Vector3::ONE * size;
         worldBox.Merge(BoundingBox(center - edge, center + edge));
-        
+
         ++enabledBillboards;
     }
-    
+
     // Always merge the node's own position to ensure particle emitter updates continue when the relative mode is switched
     worldBox.Merge(node_->GetWorldPosition());
 
@@ -406,34 +406,34 @@ void BillboardSet::OnWorldBoundingBoxUpdate()
 void BillboardSet::UpdateBufferSize()
 {
     unsigned numBillboards = billboards_.Size();
-    
+
     if (vertexBuffer_->GetVertexCount() != numBillboards * 4)
         vertexBuffer_->SetSize(numBillboards * 4, MASK_POSITION | MASK_COLOR | MASK_TEXCOORD1 | MASK_TEXCOORD2, true);
     if (indexBuffer_->GetIndexCount() != numBillboards * 6)
         indexBuffer_->SetSize(numBillboards * 6, false);
-    
+
     bufferSizeDirty_ = false;
     bufferDirty_ = true;
     forceUpdate_ = true;
-    
+
     if (!numBillboards)
         return;
-    
+
     // Indices do not change for a given billboard capacity
     unsigned short* dest = (unsigned short*)indexBuffer_->Lock(0, numBillboards * 6, true);
     if (!dest)
         return;
-    
+
     unsigned vertexIndex = 0;
     while (numBillboards--)
     {
         dest[0] = vertexIndex; dest[1] = vertexIndex + 1; dest[2] = vertexIndex + 2;
         dest[3] = vertexIndex + 2; dest[4] = vertexIndex + 3; dest[5] = vertexIndex;
-        
+
         dest += 6;
         vertexIndex += 4;
     }
-    
+
     indexBuffer_->Unlock();
     indexBuffer_->ClearDataLost();
 }
@@ -453,23 +453,23 @@ void BillboardSet::UpdateVertexBuffer(const FrameInfo& frame)
                 return;
         }
     }
-    
+
     unsigned numBillboards = billboards_.Size();
     unsigned enabledBillboards = 0;
     const Matrix3x4& worldTransform = node_->GetWorldTransform();
     Matrix3x4 billboardTransform = relative_ ? worldTransform : Matrix3x4::IDENTITY;
     Vector3 billboardScale = scaled_ ? worldTransform.Scale() : Vector3::ONE;
-    
+
     // First check number of enabled billboards
     for (unsigned i = 0; i < numBillboards; ++i)
     {
         if (billboards_[i].enabled_)
             ++enabledBillboards;
     }
-    
+
     sortedBillboards_.Resize(enabledBillboards);
     unsigned index = 0;
-    
+
     // Then set initial sort order and distances
     for (unsigned i = 0; i < numBillboards; ++i)
     {
@@ -481,52 +481,52 @@ void BillboardSet::UpdateVertexBuffer(const FrameInfo& frame)
                 billboard.sortDistance_ = frame.camera_->GetDistanceSquared(billboardTransform * billboards_[i].position_);
         }
     }
-    
+
     batches_[0].geometry_->SetDrawRange(TRIANGLE_LIST, 0, enabledBillboards * 6, false);
-    
+
     bufferDirty_ = false;
     forceUpdate_ = false;
     if (!enabledBillboards)
         return;
-    
+
     if (sorted_)
         Sort(sortedBillboards_.Begin(), sortedBillboards_.End(), CompareBillboards);
-    
+
     float* dest = (float*)vertexBuffer_->Lock(0, enabledBillboards * 4, true);
     if (!dest)
         return;
-    
+
     for (unsigned i = 0; i < enabledBillboards; ++i)
     {
         Billboard& billboard = *sortedBillboards_[i];
-        
+
         Vector2 size(billboard.size_.x_ * billboardScale.x_, billboard.size_.y_ * billboardScale.y_);
         unsigned color = billboard.color_.ToUInt();
-        
+
         float rotationMatrix[2][2];
         rotationMatrix[0][0] = Cos(billboard.rotation_);
         rotationMatrix[0][1] = Sin(billboard.rotation_);
         rotationMatrix[1][0] = -rotationMatrix[0][1];
         rotationMatrix[1][1] = rotationMatrix[0][0];
-        
+
         dest[0] = billboard.position_.x_; dest[1] = billboard.position_.y_; dest[2] = billboard.position_.z_;
         ((unsigned&)dest[3]) = color;
         dest[4] = billboard.uv_.min_.x_; dest[5] = billboard.uv_.min_.y_;
         dest[6] = -size.x_ * rotationMatrix[0][0] + size.y_ * rotationMatrix[0][1];
         dest[7] = -size.x_ * rotationMatrix[1][0] + size.y_ * rotationMatrix[1][1];
-        
+
         dest[8] = billboard.position_.x_; dest[9] = billboard.position_.y_; dest[10] = billboard.position_.z_;
         ((unsigned&)dest[11]) = color;
         dest[12] = billboard.uv_.max_.x_; dest[13] = billboard.uv_.min_.y_;
         dest[14] = size.x_ * rotationMatrix[0][0] + size.y_ * rotationMatrix[0][1];
         dest[15] = size.x_ * rotationMatrix[1][0] + size.y_ * rotationMatrix[1][1];
-        
+
         dest[16] = billboard.position_.x_; dest[17] = billboard.position_.y_; dest[18] = billboard.position_.z_;
         ((unsigned&)dest[19]) = color;
         dest[20] = billboard.uv_.max_.x_; dest[21] = billboard.uv_.max_.y_;
         dest[22] = size.x_ * rotationMatrix[0][0] - size.y_ * rotationMatrix[0][1];
         dest[23] = size.x_ * rotationMatrix[1][0] - size.y_ * rotationMatrix[1][1];
-        
+
         dest[24] = billboard.position_.x_; dest[25] = billboard.position_.y_; dest[26] = billboard.position_.z_;
         ((unsigned&)dest[27]) = color;
         dest[28] = billboard.uv_.min_.x_; dest[29] = billboard.uv_.max_.y_;
@@ -535,7 +535,7 @@ void BillboardSet::UpdateVertexBuffer(const FrameInfo& frame)
 
         dest += 32;
     }
-    
+
     vertexBuffer_->Unlock();
     vertexBuffer_->ClearDataLost();
 }

+ 11 - 11
Source/Engine/Graphics/BillboardSet.h

@@ -59,7 +59,7 @@ static const unsigned MAX_BILLBOARDS = 65536 / 4;
 class URHO3D_API BillboardSet : public Drawable
 {
     OBJECT(BillboardSet);
-    
+
 public:
     /// Construct.
     BillboardSet(Context* context);
@@ -67,7 +67,7 @@ public:
     virtual ~BillboardSet();
     /// Register object factory.
     static void RegisterObject(Context* context);
-    
+
     /// Process octree raycast. May be called from a worker thread.
     virtual void ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQueryResult>& results);
     /// Calculate distance and prepare batches for rendering. May be called from worker thread(s), possibly re-entrantly.
@@ -76,7 +76,7 @@ public:
     virtual void UpdateGeometry(const FrameInfo& frame);
     /// Return whether a geometry update is necessary, and if it can happen in a worker thread.
     virtual UpdateGeometryType GetUpdateGeometryType();
-    
+
     /// Set material.
     void SetMaterial(Material* material);
     /// Set number of billboards.
@@ -93,7 +93,7 @@ public:
     void SetAnimationLodBias(float bias);
     /// Mark for bounding box and vertex buffer update. Call after modifying the billboards.
     void Commit();
-    
+
     /// Return material.
     Material* GetMaterial() const;
     /// Return number of billboards.
@@ -112,11 +112,11 @@ public:
     FaceCameraMode GetFaceCameraMode() const { return faceCameraMode_; }
     /// Return animation LOD bias.
     float GetAnimationLodBias() const { return animationLodBias_; }
-    
+
     /// Set material attribute.
-    void SetMaterialAttr(ResourceRef value);
+    void SetMaterialAttr(const ResourceRef& value);
     /// Set billboards attribute.
-    void SetBillboardsAttr(VariantVector value);
+    void SetBillboardsAttr(const VariantVector& value);
     /// Set billboards attribute for network replication.
     void SetNetBillboardsAttr(const PODVector<unsigned char>& value);
     /// Return material attribute.
@@ -125,13 +125,13 @@ public:
     VariantVector GetBillboardsAttr() const;
     /// Return billboards attribute for network replication.
     const PODVector<unsigned char>& GetNetBillboardsAttr() const;
-    
+
 protected:
     /// Recalculate the world-space bounding box.
     virtual void OnWorldBoundingBoxUpdate();
     /// Mark billboard vertex buffer to need an update.
     void MarkPositionsDirty();
-    
+
     /// Billboards.
     PODVector<Billboard> billboards_;
     /// Coordinate axes on which camera facing is done.
@@ -148,13 +148,13 @@ protected:
     bool sorted_;
     /// Billboard rotation mode in relation to the camera.
     FaceCameraMode faceCameraMode_;
-    
+
 private:
     /// Resize billboard vertex and index buffers.
     void UpdateBufferSize();
     /// Rewrite billboard vertex buffer.
     void UpdateVertexBuffer(const FrameInfo& frame);
-    
+
     /// Geometry.
     SharedPtr<Geometry> geometry_;
     /// Vertex buffer.

+ 30 - 30
Source/Engine/Graphics/Camera.cpp

@@ -84,24 +84,24 @@ void Camera::RegisterObject(Context* context)
 {
     context->RegisterFactory<Camera>(SCENE_CATEGORY);
 
-    ACCESSOR_ATTRIBUTE(Camera, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Camera, VAR_FLOAT, "Near Clip", GetNearClip, SetNearClip, float, DEFAULT_NEARCLIP, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Camera, VAR_FLOAT, "Far Clip", GetFarClip, SetFarClip, float, DEFAULT_FARCLIP, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Camera, VAR_FLOAT, "FOV", GetFov, SetFov, float, DEFAULT_CAMERA_FOV, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Camera, VAR_FLOAT, "Aspect Ratio", GetAspectRatio, SetAspectRatioInternal, float, 1.0f, AM_DEFAULT);
-    ENUM_ATTRIBUTE(Camera, "Fill Mode", fillMode_, fillModeNames, FILL_SOLID, AM_DEFAULT);
-    ATTRIBUTE(Camera, VAR_BOOL, "Auto Aspect Ratio", autoAspectRatio_, true, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Camera, VAR_BOOL, "Orthographic", IsOrthographic, SetOrthographic, bool, false, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Camera, VAR_FLOAT, "Orthographic Size", GetOrthoSize, SetOrthoSize, float, DEFAULT_ORTHOSIZE, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Camera, VAR_FLOAT, "Zoom", GetZoom, SetZoom, float, 1.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Camera, VAR_FLOAT, "LOD Bias", GetLodBias, SetLodBias, float, 1.0f, AM_DEFAULT);
-    ATTRIBUTE(Camera, VAR_INT, "View Mask", viewMask_, DEFAULT_VIEWMASK, AM_DEFAULT);
-    ATTRIBUTE(Camera, VAR_INT, "View Override Flags", viewOverrideFlags_, VO_NONE, AM_DEFAULT);
-    REF_ACCESSOR_ATTRIBUTE(Camera, VAR_VECTOR2, "Projection Offset", GetProjectionOffset, SetProjectionOffset, Vector2, Vector2::ZERO, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Camera, VAR_VECTOR4, "Reflection Plane", GetReflectionPlaneAttr, SetReflectionPlaneAttr, Vector4, Vector4(0.0f, 1.0f, 0.0f, 0.0f), AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Camera, VAR_VECTOR4, "Clip Plane", GetClipPlaneAttr, SetClipPlaneAttr, Vector4, Vector4(0.0f, 1.0f, 0.0f, 0.0f), AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Camera, VAR_BOOL, "Use Reflection", GetUseReflection, SetUseReflection, bool, false, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Camera, VAR_BOOL, "Use Clipping", GetUseClipping, SetUseClipping, bool, false, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Near Clip", GetNearClip, SetNearClip, float, DEFAULT_NEARCLIP, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Far Clip", GetFarClip, SetFarClip, float, DEFAULT_FARCLIP, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("FOV", GetFov, SetFov, float, DEFAULT_CAMERA_FOV, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Aspect Ratio", GetAspectRatio, SetAspectRatioInternal, float, 1.0f, AM_DEFAULT);
+    ENUM_ATTRIBUTE("Fill Mode", fillMode_, fillModeNames, FILL_SOLID, AM_DEFAULT);
+    ATTRIBUTE("Auto Aspect Ratio", bool, autoAspectRatio_, true, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Orthographic", IsOrthographic, SetOrthographic, bool, false, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Orthographic Size", GetOrthoSize, SetOrthoSize, float, DEFAULT_ORTHOSIZE, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Zoom", GetZoom, SetZoom, float, 1.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("LOD Bias", GetLodBias, SetLodBias, float, 1.0f, AM_DEFAULT);
+    ATTRIBUTE("View Mask", int, viewMask_, DEFAULT_VIEWMASK, AM_DEFAULT);
+    ATTRIBUTE("View Override Flags", int, viewOverrideFlags_, VO_NONE, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Projection Offset", GetProjectionOffset, SetProjectionOffset, Vector2, Vector2::ZERO, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Reflection Plane", GetReflectionPlaneAttr, SetReflectionPlaneAttr, Vector4, Vector4(0.0f, 1.0f, 0.0f, 0.0f), AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Clip Plane", GetClipPlaneAttr, SetClipPlaneAttr, Vector4, Vector4(0.0f, 1.0f, 0.0f, 0.0f), AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Use Reflection", GetUseReflection, SetUseReflection, bool, false, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Use Clipping", GetUseClipping, SetUseClipping, bool, false, AM_DEFAULT);
 }
 
 void Camera::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
@@ -263,7 +263,7 @@ float Camera::GetNearClip() const
 Frustum Camera::GetSplitFrustum(float nearClip, float farClip) const
 {
     Frustum ret;
-    
+
     Matrix3x4 worldTransform = GetEffectiveWorldTransform();
     nearClip = Max(nearClip, GetNearClip());
     farClip = Min(farClip, farClip_);
@@ -365,7 +365,7 @@ const Frustum& Camera::GetFrustum() const
     if (frustumDirty_)
     {
         Matrix3x4 worldTransform = GetEffectiveWorldTransform();
-        
+
         if (!orthographic_)
             frustum_.Define(fov_, aspectRatio_, zoom_, GetNearClip(), farClip_, worldTransform);
         else
@@ -531,39 +531,39 @@ Quaternion Camera::GetFaceCameraRotation(const Vector3& position, const Quaterni
 {
     if (!node_)
         return rotation;
-    
+
     switch (mode)
     {
     default:
         return rotation;
-        
+
     case FC_ROTATE_XYZ:
         return node_->GetWorldRotation();
-        
+
     case FC_ROTATE_Y:
         {
             Vector3 euler = rotation.EulerAngles();
             euler.y_ = node_->GetWorldRotation().EulerAngles().y_;
             return Quaternion(euler.x_, euler.y_, euler.z_);
         }
-        
+
     case FC_LOOKAT_XYZ:
         {
             Quaternion lookAt;
             lookAt.FromLookRotation(position - node_->GetWorldPosition());
             return lookAt;
         }
-        
+
     case FC_LOOKAT_Y:
         {
             // Make the Y-only lookat happen on an XZ plane to make sure there are no unwanted transitions
             // or singularities
             Vector3 lookAtVec(position - node_->GetWorldPosition());
             lookAtVec.y_ = 0.0f;
-            
+
             Quaternion lookAt;
             lookAt.FromLookRotation(lookAtVec);
-            
+
             Vector3 euler = rotation.EulerAngles();
             euler.y_ = lookAt.EulerAngles().y_;
             return Quaternion(euler.x_, euler.y_, euler.z_);
@@ -590,7 +590,7 @@ const Matrix3x4& Camera::GetView() const
         view_ = GetEffectiveWorldTransform().Inverse();
         viewDirty_ = false;
     }
-    
+
     return view_;
 }
 
@@ -602,12 +602,12 @@ void Camera::SetAspectRatioInternal(float aspectRatio)
     MarkNetworkUpdate();
 }
 
-void Camera::SetReflectionPlaneAttr(Vector4 value)
+void Camera::SetReflectionPlaneAttr(const Vector4& value)
 {
     SetReflectionPlane(Plane(value));
 }
 
-void Camera::SetClipPlaneAttr(Vector4 value)
+void Camera::SetClipPlaneAttr(const Vector4& value)
 {
     SetClipPlane(Plane(value));
 }

+ 10 - 10
Source/Engine/Graphics/Camera.h

@@ -44,7 +44,7 @@ static const unsigned VO_DISABLE_OCCLUSION = 0x4;
 class URHO3D_API Camera : public Component
 {
     OBJECT(Camera);
-    
+
 public:
     /// Construct.
     Camera(Context* context);
@@ -52,10 +52,10 @@ public:
     virtual ~Camera();
     /// Register object factory.
     static void RegisterObject(Context* context);
-    
+
     /// Visualize the component as debug geometry.
     virtual void DrawDebugGeometry(DebugRenderer* debug, bool depthTest);
-    
+
     /// Set near clip distance.
     void SetNearClip(float nearClip);
     /// Set far clip distance.
@@ -94,7 +94,7 @@ public:
     void SetClipPlane(const Plane& plane);
     /// Set vertical flipping mode. Called internally by View to resolve OpenGL / Direct3D9 rendertarget sampling differences.
     void SetFlipVertical(bool enable);
-    
+
     /// Return far clip distance.
     float GetFarClip() const { return farClip_; }
     /// Return near clip distance.
@@ -102,7 +102,7 @@ public:
     /// Return vertical field of view in degrees.
     float GetFov() const { return fov_; }
     /// Return orthographic mode size.
-    float GetOrthoSize() const { return orthoSize_; } 
+    float GetOrthoSize() const { return orthoSize_; }
     /// Return aspect ratio.
     float GetAspectRatio() const { return aspectRatio_; }
     /// Return zoom.
@@ -169,24 +169,24 @@ public:
     Matrix3x4 GetEffectiveWorldTransform() const;
     /// Return if projection parameters are valid for rendering and raycasting.
     bool IsProjectionValid() const;
-    
+
     /// Set aspect ratio without disabling the "auto aspect ratio" mode. Called internally by View.
     void SetAspectRatioInternal(float aspectRatio);
     /// Set reflection plane attribute.
-    void SetReflectionPlaneAttr(Vector4 value);
+    void SetReflectionPlaneAttr(const Vector4& value);
     /// Return reflection plane attribute.
     Vector4 GetReflectionPlaneAttr() const;
     /// Set clipping plane attribute.
-    void SetClipPlaneAttr(Vector4 value);
+    void SetClipPlaneAttr(const Vector4& value);
     /// Return clipping plane attribute.
     Vector4 GetClipPlaneAttr() const;
-    
+
 protected:
     /// Handle node being assigned.
     virtual void OnNodeSet(Node* node);
     /// Handle node transform being dirtied.
     virtual void OnMarkedDirty(Node* node);
-    
+
 private:
     /// Cached view matrix.
     mutable Matrix3x4 view_;

+ 60 - 60
Source/Engine/Graphics/CustomGeometry.cpp

@@ -63,41 +63,41 @@ CustomGeometry::~CustomGeometry()
 void CustomGeometry::RegisterObject(Context* context)
 {
     context->RegisterFactory<CustomGeometry>(GEOMETRY_CATEGORY);
-    
-    ACCESSOR_ATTRIBUTE(CustomGeometry, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
-    ATTRIBUTE(CustomGeometry, VAR_BOOL, "Dynamic Vertex Buffer", dynamic_, false, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(CustomGeometry, VAR_BUFFER, "Geometry Data", GetGeometryDataAttr, SetGeometryDataAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_FILE|AM_NOEDIT);
-    REF_ACCESSOR_ATTRIBUTE(CustomGeometry, VAR_RESOURCEREFLIST, "Materials", GetMaterialsAttr, SetMaterialsAttr, ResourceRefList, ResourceRefList(Material::GetTypeStatic()), AM_DEFAULT);
-    ATTRIBUTE(CustomGeometry, VAR_BOOL, "Is Occluder", occluder_, false, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(CustomGeometry, VAR_BOOL, "Can Be Occluded", IsOccludee, SetOccludee, bool, true, AM_DEFAULT);
-    ATTRIBUTE(CustomGeometry, VAR_BOOL, "Cast Shadows", castShadows_, false, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(CustomGeometry, VAR_FLOAT, "Draw Distance", GetDrawDistance, SetDrawDistance, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(CustomGeometry, VAR_FLOAT, "Shadow Distance", GetShadowDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(CustomGeometry, VAR_FLOAT, "LOD Bias", GetLodBias, SetLodBias, float, 1.0f, AM_DEFAULT);
-    COPY_BASE_ATTRIBUTES(CustomGeometry, Drawable);
+
+    ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
+    ATTRIBUTE("Dynamic Vertex Buffer", bool, dynamic_, false, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Geometry Data", GetGeometryDataAttr, SetGeometryDataAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_FILE|AM_NOEDIT);
+    ACCESSOR_ATTRIBUTE("Materials", GetMaterialsAttr, SetMaterialsAttr, ResourceRefList, ResourceRefList(Material::GetTypeStatic()), AM_DEFAULT);
+    ATTRIBUTE("Is Occluder", bool, occluder_, false, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Can Be Occluded", IsOccludee, SetOccludee, bool, true, AM_DEFAULT);
+    ATTRIBUTE("Cast Shadows", bool, castShadows_, false, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Draw Distance", GetDrawDistance, SetDrawDistance, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Shadow Distance", GetShadowDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("LOD Bias", GetLodBias, SetLodBias, float, 1.0f, AM_DEFAULT);
+    COPY_BASE_ATTRIBUTES(Drawable);
 }
 
 void CustomGeometry::ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQueryResult>& results)
 {
     RayQueryLevel level = query.level_;
-    
+
     switch (level)
     {
     case RAY_AABB:
         Drawable::ProcessRayQuery(query, results);
         break;
-        
+
     case RAY_OBB:
     case RAY_TRIANGLE:
         Matrix3x4 inverse(node_->GetWorldTransform().Inverse());
         Ray localRay = query.ray_.Transformed(inverse);
         float distance = localRay.HitDistance(boundingBox_);
         Vector3 normal = -query.ray_.direction_;
-        
+
         if (level == RAY_TRIANGLE && distance < query.maxDistance_)
         {
             distance = M_INFINITY;
-            
+
             for (unsigned i = 0; i < batches_.Size(); ++i)
             {
                 Geometry* geometry = batches_[i].geometry_;
@@ -113,7 +113,7 @@ void CustomGeometry::ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQ
                 }
             }
         }
-        
+
         if (distance < query.maxDistance_)
         {
             RayQueryResult result;
@@ -137,34 +137,34 @@ Geometry* CustomGeometry::GetLodGeometry(unsigned batchIndex, unsigned level)
 unsigned CustomGeometry::GetNumOccluderTriangles()
 {
     unsigned triangles = 0;
-    
+
     for (unsigned i = 0; i < batches_.Size(); ++i)
     {
         Geometry* geometry = GetLodGeometry(i, 0);
         if (!geometry)
             continue;
-        
+
         // Check that the material is suitable for occlusion (default material always is)
         Material* mat = batches_[i].material_;
         if (mat && !mat->GetOcclusion())
             continue;
-        
+
         triangles += geometry->GetVertexCount() / 3;
     }
-    
+
     return triangles;
 }
 
 bool CustomGeometry::DrawOcclusion(OcclusionBuffer* buffer)
 {
     bool success = true;
-    
+
     for (unsigned i = 0; i < batches_.Size(); ++i)
     {
         Geometry* geometry = GetLodGeometry(i, 0);
         if (!geometry)
             continue;
-        
+
         // Check that the material is suitable for occlusion (default material always is) and set culling mode
         Material* material = batches_[i].material_;
         if (material)
@@ -175,25 +175,25 @@ bool CustomGeometry::DrawOcclusion(OcclusionBuffer* buffer)
         }
         else
             buffer->SetCullMode(CULL_CCW);
-        
+
         const unsigned char* vertexData;
         unsigned vertexSize;
         const unsigned char* indexData;
         unsigned indexSize;
         unsigned elementMask;
-        
+
         geometry->GetRawData(vertexData, vertexSize, indexData, indexSize, elementMask);
         // Check for valid geometry data
         if (!vertexData)
             continue;
-        
+
         // Draw and check for running out of triangles
         success = buffer->Draw(node_->GetWorldTransform(), vertexData, vertexSize, geometry->GetVertexStart(), geometry->GetVertexCount());
-        
+
         if (!success)
             break;
     }
-    
+
     return success;
 }
 
@@ -212,12 +212,12 @@ void CustomGeometry::SetNumGeometries(unsigned num)
     geometries_.Resize(num);
     primitiveTypes_.Resize(num);
     vertices_.Resize(num);
-    
+
     for (unsigned i = 0; i < geometries_.Size(); ++i)
     {
         if (!geometries_[i])
             geometries_[i] = new Geometry(context_);
-        
+
         batches_[i].geometry_ = geometries_[i];
     }
 }
@@ -236,7 +236,7 @@ void CustomGeometry::BeginGeometry(unsigned index, PrimitiveType type)
         LOGERROR("Geometry index out of bounds");
         return;
     }
-    
+
     geometryIndex_ = index;
     primitiveTypes_[index] = type;
     vertices_[index].Clear();
@@ -250,7 +250,7 @@ void CustomGeometry::DefineVertex(const Vector3& position)
 {
     if (vertices_.Size() < geometryIndex_)
         return;
-    
+
     vertices_[geometryIndex_].Resize(vertices_[geometryIndex_].Size() + 1);
     vertices_[geometryIndex_].Back().position_ = position;
 }
@@ -259,7 +259,7 @@ void CustomGeometry::DefineNormal(const Vector3& normal)
 {
     if (vertices_.Size() < geometryIndex_ || vertices_[geometryIndex_].Empty())
         return;
-    
+
     vertices_[geometryIndex_].Back().normal_ = normal;
     elementMask_ |= MASK_NORMAL;
 }
@@ -268,7 +268,7 @@ void CustomGeometry::DefineColor(const Color& color)
 {
     if (vertices_.Size() < geometryIndex_ || vertices_[geometryIndex_].Empty())
         return;
-    
+
     vertices_[geometryIndex_].Back().color_ = color.ToUInt();
     elementMask_ |= MASK_COLOR;
 }
@@ -277,7 +277,7 @@ void CustomGeometry::DefineTexCoord(const Vector2& texCoord)
 {
     if (vertices_.Size() < geometryIndex_ || vertices_[geometryIndex_].Empty())
         return;
-    
+
     vertices_[geometryIndex_].Back().texCoord_ = texCoord;
     elementMask_ |= MASK_TEXCOORD1;
 }
@@ -286,7 +286,7 @@ void CustomGeometry::DefineTangent(const Vector4& tangent)
 {
     if (vertices_.Size() < geometryIndex_ || vertices_[geometryIndex_].Empty())
         return;
-    
+
     vertices_[geometryIndex_].Back().tangent_ = tangent;
     elementMask_ |= MASK_TANGENT;
 }
@@ -319,18 +319,18 @@ void CustomGeometry::DefineGeometry(unsigned index, PrimitiveType type, unsigned
 void CustomGeometry::Commit()
 {
     PROFILE(CommitCustomGeometry);
-    
+
     unsigned totalVertices = 0;
     boundingBox_.Clear();
-    
+
     for (unsigned i = 0; i < vertices_.Size(); ++i)
     {
         totalVertices += vertices_[i].Size();
-        
+
         for (unsigned j = 0; j < vertices_[i].Size(); ++j)
             boundingBox_.Merge(vertices_[i][j].position_);
     }
-    
+
     // Resize (recreate) the vertex buffer only if necessary
     if (vertexBuffer_->GetVertexCount() != totalVertices || vertexBuffer_->GetElementMask() != elementMask_ ||
         vertexBuffer_->IsDynamic() != dynamic_)
@@ -342,16 +342,16 @@ void CustomGeometry::Commit()
         if (dest)
         {
             unsigned vertexStart = 0;
-            
+
             for (unsigned i = 0; i < vertices_.Size(); ++i)
             {
                 unsigned vertexCount = 0;
-                
+
                 for (unsigned j = 0; j < vertices_[i].Size(); ++j)
                 {
                     *((Vector3*)dest) = vertices_[i][j].position_;
                     dest += sizeof(Vector3);
-                    
+
                     if (elementMask_ & MASK_NORMAL)
                     {
                         *((Vector3*)dest) = vertices_[i][j].normal_;
@@ -372,15 +372,15 @@ void CustomGeometry::Commit()
                         *((Vector4*)dest) = vertices_[i][j].tangent_;
                         dest += sizeof(Vector4);
                     }
-                    
+
                     ++vertexCount;
                 }
-                
+
                 geometries_[i]->SetVertexBuffer(0, vertexBuffer_, elementMask_);
                 geometries_[i]->SetDrawRange(primitiveTypes_[i], 0, 0, vertexStart, vertexCount);
                 vertexStart += vertexCount;
             }
-            
+
             vertexBuffer_->Unlock();
         }
         else
@@ -394,7 +394,7 @@ void CustomGeometry::Commit()
             geometries_[i]->SetDrawRange(primitiveTypes_[i], 0, 0, 0, 0);
         }
     }
-    
+
     vertexBuffer_->ClearDataLost();
 }
 
@@ -402,7 +402,7 @@ void CustomGeometry::SetMaterial(Material* material)
 {
     for (unsigned i = 0; i < batches_.Size(); ++i)
         batches_[i].material_ = material;
-    
+
     MarkNetworkUpdate();
 }
 
@@ -413,7 +413,7 @@ bool CustomGeometry::SetMaterial(unsigned index, Material* material)
         LOGERROR("Material index out of bounds");
         return false;
     }
-    
+
     batches_[index].material_ = material;
     MarkNetworkUpdate();
     return true;
@@ -435,22 +435,22 @@ CustomGeometryVertex* CustomGeometry::GetVertex(unsigned geometryIndex, unsigned
         &vertices_[geometryIndex][vertexNum] : (CustomGeometryVertex*)0;
 }
 
-void CustomGeometry::SetGeometryDataAttr(PODVector<unsigned char> value)
+void CustomGeometry::SetGeometryDataAttr(const PODVector<unsigned char>& value)
 {
     if (value.Empty())
         return;
-    
+
     MemoryBuffer buffer(value);
-    
+
     SetNumGeometries(buffer.ReadVLE());
     elementMask_ = buffer.ReadUInt();
-    
+
     for (unsigned i = 0; i < geometries_.Size(); ++i)
     {
         unsigned numVertices = buffer.ReadVLE();
         vertices_[i].Resize(numVertices);
         primitiveTypes_[i] = (PrimitiveType)buffer.ReadUByte();
-        
+
         for (unsigned j = 0; j < numVertices; ++j)
         {
              if (elementMask_ & MASK_POSITION)
@@ -465,7 +465,7 @@ void CustomGeometry::SetGeometryDataAttr(PODVector<unsigned char> value)
                 vertices_[i][j].tangent_ = buffer.ReadVector4();
         }
     }
-    
+
     Commit();
 }
 
@@ -479,16 +479,16 @@ void CustomGeometry::SetMaterialsAttr(const ResourceRefList& value)
 PODVector<unsigned char> CustomGeometry::GetGeometryDataAttr() const
 {
     VectorBuffer ret;
-    
+
     ret.WriteVLE(geometries_.Size());
     ret.WriteUInt(elementMask_);
-    
+
     for (unsigned i = 0; i < geometries_.Size(); ++i)
     {
         unsigned numVertices = vertices_[i].Size();
         ret.WriteVLE(numVertices);
         ret.WriteUByte(primitiveTypes_[i]);
-        
+
         for (unsigned j = 0; j < numVertices; ++j)
         {
              if (elementMask_ & MASK_POSITION)
@@ -503,7 +503,7 @@ PODVector<unsigned char> CustomGeometry::GetGeometryDataAttr() const
                 ret.WriteVector4(vertices_[i][j].tangent_);
         }
     }
-    
+
     return ret.GetBuffer();
 }
 
@@ -512,7 +512,7 @@ const ResourceRefList& CustomGeometry::GetMaterialsAttr() const
     materialsAttr_.names_.Resize(batches_.Size());
     for (unsigned i = 0; i < batches_.Size(); ++i)
         materialsAttr_.names_[i] = GetResourceName(batches_[i].material_);
-    
+
     return materialsAttr_;
 }
 

+ 6 - 6
Source/Engine/Graphics/CustomGeometry.h

@@ -48,7 +48,7 @@ class VertexBuffer;
 class URHO3D_API CustomGeometry : public Drawable
 {
     OBJECT(CustomGeometry);
-    
+
 public:
     /// Construct.
     CustomGeometry(Context* context);
@@ -56,7 +56,7 @@ public:
     virtual ~CustomGeometry();
     /// Register object factory. Drawable must be registered first.
     static void RegisterObject(Context* context);
-    
+
     /// Process octree raycast. May be called from a worker thread.
     virtual void ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQueryResult>& results);
     /// Return the geometry for a specific LOD level.
@@ -65,7 +65,7 @@ public:
     virtual unsigned GetNumOccluderTriangles();
     /// Draw to occlusion buffer. Return true if did not run out of triangles.
     virtual bool DrawOcclusion(OcclusionBuffer* buffer);
-    
+
     /// Clear all geometries.
     void Clear();
     /// Set number of geometries.
@@ -107,18 +107,18 @@ public:
     CustomGeometryVertex* GetVertex(unsigned geometryIndex, unsigned vertexNum);
 
     /// Set geometry data attribute.
-    void SetGeometryDataAttr(PODVector<unsigned char> value);
+    void SetGeometryDataAttr(const PODVector<unsigned char>& value);
     /// Set materials attribute.
     void SetMaterialsAttr(const ResourceRefList& value);
     /// Return geometry data attribute.
     PODVector<unsigned char> GetGeometryDataAttr() const;
     /// Return materials attribute.
     const ResourceRefList& GetMaterialsAttr() const;
-    
+
 protected:
     /// Recalculate the world-space bounding box.
     virtual void OnWorldBoundingBoxUpdate();
-    
+
 private:
     /// Primitive type per geometry.
     PODVector<PrimitiveType> primitiveTypes_;

+ 136 - 136
Source/Engine/Graphics/DecalSet.cpp

@@ -61,7 +61,7 @@ static DecalVertex ClipEdge(const DecalVertex& v0, const DecalVertex& v1, float
 {
     DecalVertex ret;
     float t = d0 / (d0 - d1);
-    
+
     ret.position_ = v0.position_ + t * (v1.position_ - v0.position_);
     ret.normal_ = v0.normal_ + t * (v1.normal_ - v0.normal_);
     if (skinned)
@@ -86,7 +86,7 @@ static DecalVertex ClipEdge(const DecalVertex& v0, const DecalVertex& v1, float
             }
         }
     }
-    
+
     return ret;
 }
 
@@ -95,10 +95,10 @@ static void ClipPolygon(PODVector<DecalVertex>& dest, const PODVector<DecalVerte
     unsigned last;
     float lastDistance = 0.0f;
     dest.Clear();
-    
+
     if (src.Empty())
         return;
-    
+
     for (unsigned i = 0; i < src.Size(); ++i)
     {
         float distance = plane.Distance(src[i].position_);
@@ -106,7 +106,7 @@ static void ClipPolygon(PODVector<DecalVertex>& dest, const PODVector<DecalVerte
         {
             if (lastDistance < 0.0f)
                 dest.Push(ClipEdge(src[last], src[i], lastDistance, distance, skinned));
-            
+
             dest.Push(src[i]);
         }
         else
@@ -114,11 +114,11 @@ static void ClipPolygon(PODVector<DecalVertex>& dest, const PODVector<DecalVerte
             if (lastDistance >= 0.0f && i != 0)
                 dest.Push(ClipEdge(src[last], src[i], lastDistance, distance, skinned));
         }
-        
+
         last = i;
         lastDistance = distance;
     }
-    
+
     // Recheck the distances of the last and first vertices and add the final clipped vertex if applicable
     float distance = plane.Distance(src[0].position_);
     if ((lastDistance < 0.0f && distance >= 0.0f) || (lastDistance >= 0.0f && distance < 0.0f))
@@ -135,7 +135,7 @@ void Decal::AddVertex(const DecalVertex& vertex)
             return;
         }
     }
-    
+
     unsigned short newIndex = vertices_.Size();
     vertices_.Push(vertex);
     indices_.Push(newIndex);
@@ -166,7 +166,7 @@ DecalSet::DecalSet(Context* context) :
     subscribed_(false)
 {
     geometry_->SetIndexBuffer(indexBuffer_);
-    
+
     batches_.Resize(1);
     batches_[0].geometry_ = geometry_;
     batches_[0].geometryType_ = GEOM_STATIC_NOINSTANCING;
@@ -179,15 +179,15 @@ DecalSet::~DecalSet()
 void DecalSet::RegisterObject(Context* context)
 {
     context->RegisterFactory<DecalSet>(GEOMETRY_CATEGORY);
-    
-    ACCESSOR_ATTRIBUTE(DecalSet, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(DecalSet, VAR_RESOURCEREF, "Material", GetMaterialAttr, SetMaterialAttr, ResourceRef, ResourceRef(Material::GetTypeStatic()), AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(DecalSet, VAR_INT, "Max Vertices", GetMaxVertices, SetMaxVertices, unsigned, DEFAULT_MAX_VERTICES, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(DecalSet, VAR_INT, "Max Indices", GetMaxIndices, SetMaxIndices, unsigned, DEFAULT_MAX_INDICES, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(DecalSet, VAR_BOOL, "Can Be Occluded", IsOccludee, SetOccludee, bool, true, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(DecalSet, VAR_FLOAT, "Draw Distance", GetDrawDistance, SetDrawDistance, float, 0.0f, AM_DEFAULT);
-    COPY_BASE_ATTRIBUTES(DecalSet, Drawable);
-    ACCESSOR_ATTRIBUTE(DecalSet, VAR_BUFFER, "Decals", GetDecalsAttr, SetDecalsAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_FILE | AM_NOEDIT);
+
+    ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Material", GetMaterialAttr, SetMaterialAttr, ResourceRef, ResourceRef(Material::GetTypeStatic()), AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Max Vertices", GetMaxVertices, SetMaxVertices, unsigned, DEFAULT_MAX_VERTICES, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Max Indices", GetMaxIndices, SetMaxIndices, unsigned, DEFAULT_MAX_INDICES, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Can Be Occluded", IsOccludee, SetOccludee, bool, true, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Draw Distance", GetDrawDistance, SetDrawDistance, float, 0.0f, AM_DEFAULT);
+    COPY_BASE_ATTRIBUTES(Drawable);
+    MIXED_ACCESSOR_ATTRIBUTE("Decals", GetDecalsAttr, SetDecalsAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_FILE | AM_NOEDIT);
 }
 
 void DecalSet::ApplyAttributes()
@@ -199,7 +199,7 @@ void DecalSet::ApplyAttributes()
 void DecalSet::OnSetEnabled()
 {
     Drawable::OnSetEnabled();
-    
+
     UpdateEventSubscription(true);
 }
 
@@ -213,10 +213,10 @@ void DecalSet::UpdateBatches(const FrameInfo& frame)
     const BoundingBox& worldBoundingBox = GetWorldBoundingBox();
     const Matrix3x4& worldTransform = node_->GetWorldTransform();
     distance_ = frame.camera_->GetDistance(worldBoundingBox.Center());
-    
+
     float scale = worldBoundingBox.Size().DotProduct(DOT_SCALE);
     lodDistance_ = frame.camera_->GetLodDistance(distance_, scale, lodBias_);
-    
+
     batches_[0].distance_ = distance_;
     if (!skinned_)
         batches_[0].worldTransform_ = &worldTransform;
@@ -226,10 +226,10 @@ void DecalSet::UpdateGeometry(const FrameInfo& frame)
 {
     if (bufferSizeDirty_)
         UpdateBufferSize();
-    
+
     if (bufferDirty_ || vertexBuffer_->IsDataLost() || indexBuffer_->IsDataLost())
         UpdateBuffers();
-    
+
     if (skinningDirty_)
         UpdateSkinning();
 }
@@ -254,15 +254,15 @@ void DecalSet::SetMaxVertices(unsigned num)
 {
     // Never expand to 32 bit indices
     num = Clamp((int)num, MIN_VERTICES, MAX_VERTICES);
-    
+
     if (num != maxVertices_)
     {
         bufferSizeDirty_ = true;
         maxVertices_ = num;
-        
+
         while (decals_.Size() && numVertices_ > maxVertices_)
             RemoveDecals(1);
-        
+
         MarkNetworkUpdate();
     }
 }
@@ -271,15 +271,15 @@ void DecalSet::SetMaxIndices(unsigned num)
 {
     if (num < MIN_INDICES)
         num = MIN_INDICES;
-    
+
     if (num != maxIndices_)
     {
         bufferSizeDirty_ = true;
         maxIndices_ = num;
-        
+
         while (decals_.Size() && numIndices_ > maxIndices_)
             RemoveDecals(1);
-        
+
         MarkNetworkUpdate();
     }
 }
@@ -289,17 +289,17 @@ bool DecalSet::AddDecal(Drawable* target, const Vector3& worldPosition, const Qu
     unsigned subGeometry)
 {
     PROFILE(AddDecal);
-    
+
     // Do not add decals in headless mode
     if (!node_ || !GetSubsystem<Graphics>())
         return false;
-    
+
     if (!target || !target->GetNode())
     {
         LOGERROR("Null target drawable for decal");
         return false;
     }
-    
+
     // Check for animated target and switch into skinned/static mode if necessary
     AnimatedModel* animatedModel = dynamic_cast<AnimatedModel*>(target);
     if ((animatedModel && !skinned_) || (!animatedModel && skinned_))
@@ -308,12 +308,12 @@ bool DecalSet::AddDecal(Drawable* target, const Vector3& worldPosition, const Qu
         skinned_ = animatedModel != 0;
         bufferSizeDirty_ = true;
     }
-    
+
     // Center the decal frustum on the world position
     Vector3 adjustedWorldPosition = worldPosition - 0.5f * depth * (worldRotation * Vector3::FORWARD);
     /// \todo target transform is not right if adding a decal to StaticModelGroup
     Matrix3x4 targetTransform = target->GetNode()->GetWorldTransform().Inverse();
-    
+
     // For an animated model, adjust the decal position back to the bind pose
     // To do this, need to find the bone the decal is colliding with
     if (animatedModel)
@@ -322,17 +322,17 @@ bool DecalSet::AddDecal(Drawable* target, const Vector3& worldPosition, const Qu
         unsigned numBones = skeleton.GetNumBones();
         Bone* bestBone = 0;
         float bestSize = 0.0f;
-        
+
         for (unsigned i = 0; i < numBones; ++i)
         {
             Bone* bone = skeleton.GetBone(i);
             if (!bone->node_ || !bone->collisionMask_)
                 continue;
-            
+
             // Represent the decal as a sphere, try to find the biggest colliding bone
             Sphere decalSphere(bone->node_->GetWorldTransform().Inverse() * worldPosition, 0.5f * size /
                 bone->node_->GetWorldScale().Length());
-            
+
             if (bone->collisionMask_ & BONECOLLISION_BOX)
             {
                 float size = bone->boundingBox_.HalfSize().Length();
@@ -353,27 +353,27 @@ bool DecalSet::AddDecal(Drawable* target, const Vector3& worldPosition, const Qu
                 }
             }
         }
-        
+
         if (bestBone)
             targetTransform = (bestBone->node_->GetWorldTransform() * bestBone->offsetMatrix_).Inverse();
     }
-    
+
     // Build the decal frustum
     Frustum decalFrustum;
     Matrix3x4 frustumTransform = targetTransform * Matrix3x4(adjustedWorldPosition, worldRotation, 1.0f);
     decalFrustum.DefineOrtho(size, aspectRatio, 1.0, 0.0f, depth, frustumTransform);
-    
+
     Vector3 decalNormal = (targetTransform * Vector4(worldRotation * Vector3::BACK, 0.0f)).Normalized();
-    
+
     decals_.Resize(decals_.Size() + 1);
     Decal& newDecal = decals_.Back();
     newDecal.timeToLive_ = timeToLive;
-    
+
     Vector<PODVector<DecalVertex> > faces;
     PODVector<DecalVertex> tempFace;
-    
+
     unsigned numBatches = target->GetBatches().Size();
-    
+
     // Use either a specified subgeometry in the target, or all
     if (subGeometry < numBatches)
         GetFaces(faces, target, subGeometry, decalFrustum, decalNormal, normalCutoff);
@@ -382,7 +382,7 @@ bool DecalSet::AddDecal(Drawable* target, const Vector3& worldPosition, const Qu
         for (unsigned i = 0; i < numBatches; ++i)
             GetFaces(faces, target, i, decalFrustum, decalNormal, normalCutoff);
     }
-    
+
     // Clip the acquired faces against all frustum planes
     for (unsigned i = 0; i < NUM_FRUSTUM_PLANES; ++i)
     {
@@ -391,19 +391,19 @@ bool DecalSet::AddDecal(Drawable* target, const Vector3& worldPosition, const Qu
             PODVector<DecalVertex>& face = faces[j];
             if (face.Empty())
                 continue;
-            
+
             ClipPolygon(tempFace, face, decalFrustum.planes_[i], skinned_);
             face = tempFace;
         }
     }
-    
+
     // Now triangulate the resulting faces into decal vertices
     for (unsigned i = 0; i < faces.Size(); ++i)
     {
         PODVector<DecalVertex>& face = faces[i];
         if (face.Size() < 3)
             continue;
-        
+
         for (unsigned j = 2; j < face.Size(); ++j)
         {
             newDecal.AddVertex(face[0]);
@@ -411,14 +411,14 @@ bool DecalSet::AddDecal(Drawable* target, const Vector3& worldPosition, const Qu
             newDecal.AddVertex(face[j]);
         }
     }
-    
+
     // Check if resulted in no triangles
     if (newDecal.vertices_.Empty())
     {
         decals_.Pop();
         return true;
     }
-    
+
     if (newDecal.vertices_.Size() > maxVertices_)
     {
         LOGWARNING("Can not add decal, vertex count " + String(newDecal.vertices_.Size()) + " exceeds maximum " +
@@ -433,37 +433,37 @@ bool DecalSet::AddDecal(Drawable* target, const Vector3& worldPosition, const Qu
         decals_.Pop();
         return false;
     }
-    
+
     // Calculate UVs
     Matrix4 projection(Matrix4::ZERO);
     projection.m11_ = (1.0f / (size * 0.5f));
     projection.m00_ = projection.m11_ / aspectRatio;
     projection.m22_ = 1.0f / depth;
     projection.m33_ = 1.0f;
-    
+
     CalculateUVs(newDecal, frustumTransform.Inverse(), projection, topLeftUV, bottomRightUV);
-    
+
     // Transform vertices to this node's local space and generate tangents
     Matrix3x4 decalTransform = node_->GetWorldTransform().Inverse() * target->GetNode()->GetWorldTransform();
     TransformVertices(newDecal, skinned_ ? Matrix3x4::IDENTITY : decalTransform);
     GenerateTangents(&newDecal.vertices_[0], sizeof(DecalVertex), &newDecal.indices_[0], sizeof(unsigned short), 0,
         newDecal.indices_.Size(), offsetof(DecalVertex, normal_), offsetof(DecalVertex, texCoord_), offsetof(DecalVertex,
         tangent_));
-    
+
     newDecal.CalculateBoundingBox();
     numVertices_ += newDecal.vertices_.Size();
     numIndices_ += newDecal.indices_.Size();
-    
+
     // Remove oldest decals if total vertices exceeded
     while (decals_.Size() && (numVertices_ > maxVertices_ || numIndices_ > maxIndices_))
         RemoveDecals(1);
-    
+
     LOGDEBUG("Added decal with " + String(newDecal.vertices_.Size()) + " vertices");
-    
+
     // If new decal is time limited, subscribe to scene post-update
     if (newDecal.timeToLive_ > 0.0f && !subscribed_)
         UpdateEventSubscription(false);
-    
+
     MarkDecalsDirty();
     return true;
 }
@@ -483,14 +483,14 @@ void DecalSet::RemoveAllDecals()
         numIndices_ = 0;
         MarkDecalsDirty();
     }
-    
+
     // Remove all bones and skinning matrices and stop listening to the bone nodes
     for (Vector<Bone>::Iterator i = bones_.Begin(); i != bones_.End(); ++i)
     {
         if (i->node_)
             i->node_->RemoveListener(this);
     }
-    
+
     bones_.Clear();
     skinMatrices_.Clear();
     UpdateBatch();
@@ -501,34 +501,34 @@ Material* DecalSet::GetMaterial() const
     return batches_[0].material_;
 }
 
-void DecalSet::SetMaterialAttr(ResourceRef value)
+void DecalSet::SetMaterialAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SetMaterial(cache->GetResource<Material>(value.name_));
 }
 
-void DecalSet::SetDecalsAttr(PODVector<unsigned char> value)
+void DecalSet::SetDecalsAttr(const PODVector<unsigned char>& value)
 {
     RemoveAllDecals();
-    
+
     if (value.Empty())
         return;
-    
+
     MemoryBuffer buffer(value);
-    
+
     skinned_ = buffer.ReadBool();
     unsigned numDecals = buffer.ReadVLE();
-    
+
     while (numDecals--)
     {
         decals_.Resize(decals_.Size() + 1);
         Decal& newDecal = decals_.Back();
-        
+
         newDecal.timer_ = buffer.ReadFloat();
         newDecal.timeToLive_ = buffer.ReadFloat();
         newDecal.vertices_.Resize(buffer.ReadVLE());
         newDecal.indices_.Resize(buffer.ReadVLE());
-    
+
         for (PODVector<DecalVertex>::Iterator i = newDecal.vertices_.Begin(); i != newDecal.vertices_.End(); ++i)
         {
             i->position_ = buffer.ReadVector3();
@@ -543,25 +543,25 @@ void DecalSet::SetDecalsAttr(PODVector<unsigned char> value)
                     i->blendIndices_[j] = buffer.ReadUByte();
             }
         }
-        
+
         for (PODVector<unsigned short>::Iterator i = newDecal.indices_.Begin(); i != newDecal.indices_.End(); ++i)
             *i = buffer.ReadUShort();
-        
+
         newDecal.CalculateBoundingBox();
         numVertices_ += newDecal.vertices_.Size();
         numIndices_ += newDecal.indices_.Size();
     }
-    
+
     if (skinned_)
     {
         unsigned numBones = buffer.ReadVLE();
         skinMatrices_.Resize(numBones);
         bones_.Resize(numBones);
-        
+
         for (unsigned i = 0; i < numBones; ++i)
         {
             Bone& newBone = bones_[i];
-            
+
             newBone.name_ = buffer.ReadString();
             newBone.collisionMask_ = buffer.ReadUByte();
             if (newBone.collisionMask_ & BONECOLLISION_SPHERE)
@@ -570,11 +570,11 @@ void DecalSet::SetDecalsAttr(PODVector<unsigned char> value)
                 newBone.boundingBox_ = buffer.ReadBoundingBox();
             buffer.Read(&newBone.offsetMatrix_.m00_, sizeof(Matrix3x4));
         }
-        
+
         assignBonesPending_ = true;
         skinningDirty_ = true;
     }
-    
+
     UpdateEventSubscription(true);
     UpdateBatch();
     MarkDecalsDirty();
@@ -589,17 +589,17 @@ ResourceRef DecalSet::GetMaterialAttr() const
 PODVector<unsigned char> DecalSet::GetDecalsAttr() const
 {
     VectorBuffer ret;
-    
+
     ret.WriteBool(skinned_);
     ret.WriteVLE(decals_.Size());
-    
+
     for (List<Decal>::ConstIterator i = decals_.Begin(); i != decals_.End(); ++i)
     {
         ret.WriteFloat(i->timer_);
         ret.WriteFloat(i->timeToLive_);
         ret.WriteVLE(i->vertices_.Size());
         ret.WriteVLE(i->indices_.Size());
-        
+
         for (PODVector<DecalVertex>::ConstIterator j = i->vertices_.Begin(); j != i->vertices_.End(); ++j)
         {
             ret.WriteVector3(j->position_);
@@ -614,15 +614,15 @@ PODVector<unsigned char> DecalSet::GetDecalsAttr() const
                     ret.WriteUByte(j->blendIndices_[k]);
             }
         }
-        
+
         for (PODVector<unsigned short>::ConstIterator j = i->indices_.Begin(); j != i->indices_.End(); ++j)
             ret.WriteUShort(*j);
     }
-    
+
     if (skinned_)
     {
         ret.WriteVLE(bones_.Size());
-        
+
         for (Vector<Bone>::ConstIterator i = bones_.Begin(); i != bones_.End(); ++i)
         {
             ret.WriteString(i->name_);
@@ -634,14 +634,14 @@ PODVector<unsigned char> DecalSet::GetDecalsAttr() const
             ret.Write(i->offsetMatrix_.Data(), sizeof(Matrix3x4));
         }
     }
-    
+
     return ret.GetBuffer();
 }
 
 void DecalSet::OnMarkedDirty(Node* node)
 {
     Drawable::OnMarkedDirty(node);
-    
+
     if (skinned_)
     {
         // If the scene node or any of the bone nodes move, mark skinning dirty
@@ -655,20 +655,20 @@ void DecalSet::OnWorldBoundingBoxUpdate()
     {
         if (boundingBoxDirty_)
             CalculateBoundingBox();
-        
+
         worldBoundingBox_ = boundingBox_.Transformed(node_->GetWorldTransform());
     }
     else
     {
         // When using skinning, update world bounding box based on the bones
         BoundingBox worldBox;
-        
+
         for (Vector<Bone>::ConstIterator i = bones_.Begin(); i != bones_.End(); ++i)
         {
             Node* boneNode = i->node_;
             if (!boneNode)
                 continue;
-            
+
             // Use hitbox if available. If not, use only half of the sphere radius
             /// \todo The sphere radius should be multiplied with bone scale
             if (i->collisionMask_ & BONECOLLISION_BOX)
@@ -688,7 +688,7 @@ void DecalSet::GetFaces(Vector<PODVector<DecalVertex> >& faces, Drawable* target
     Geometry* geometry = target->GetLodGeometry(batchIndex, 0);
     if (!geometry || geometry->GetPrimitiveType() != TRIANGLE_LIST)
         return;
-    
+
     const unsigned char* positionData = 0;
     const unsigned char* normalData = 0;
     const unsigned char* skinningData = 0;
@@ -697,26 +697,26 @@ void DecalSet::GetFaces(Vector<PODVector<DecalVertex> >& faces, Drawable* target
     unsigned normalStride = 0;
     unsigned skinningStride = 0;
     unsigned indexStride = 0;
-    
+
     IndexBuffer* ib = geometry->GetIndexBuffer();
     if (ib)
     {
         indexData = ib->GetShadowData();
         indexStride = ib->GetIndexSize();
     }
-    
+
     // For morphed models positions, normals and skinning may be in different buffers
     for (unsigned i = 0; i < geometry->GetNumVertexBuffers(); ++i)
     {
         VertexBuffer* vb = geometry->GetVertexBuffer(i);
         if (!vb)
             continue;
-        
+
         unsigned elementMask = geometry->GetVertexElementMask(i);
         unsigned char* data = vb->GetShadowData();
         if (!data)
             continue;
-        
+
         if (elementMask & MASK_POSITION)
         {
             positionData = data;
@@ -733,7 +733,7 @@ void DecalSet::GetFaces(Vector<PODVector<DecalVertex> >& faces, Drawable* target
             skinningStride = vb->GetVertexSize();
         }
     }
-    
+
     // Positions and indices are needed
     if (!positionData)
     {
@@ -746,18 +746,18 @@ void DecalSet::GetFaces(Vector<PODVector<DecalVertex> >& faces, Drawable* target
             return;
         }
     }
-    
+
     if (indexData)
     {
         unsigned indexStart = geometry->GetIndexStart();
         unsigned indexCount = geometry->GetIndexCount();
-        
+
         // 16-bit indices
         if (indexStride == sizeof(unsigned short))
         {
             const unsigned short* indices = ((const unsigned short*)indexData) + indexStart;
             const unsigned short* indicesEnd = indices + indexCount;
-            
+
             while (indices < indicesEnd)
             {
                 GetFace(faces, target, batchIndex, indices[0], indices[1], indices[2], positionData, normalData, skinningData,
@@ -770,7 +770,7 @@ void DecalSet::GetFaces(Vector<PODVector<DecalVertex> >& faces, Drawable* target
         {
             const unsigned* indices = ((const unsigned*)indexData) + indexStart;
             const unsigned* indicesEnd = indices + indexCount;
-            
+
             while (indices < indicesEnd)
             {
                 GetFace(faces, target, batchIndex, indices[0], indices[1], indices[2], positionData, normalData, skinningData,
@@ -784,7 +784,7 @@ void DecalSet::GetFaces(Vector<PODVector<DecalVertex> >& faces, Drawable* target
         // Non-indexed geometry
         unsigned indices = geometry->GetVertexStart();
         unsigned indicesEnd = indices + geometry->GetVertexCount();
-        
+
         while (indices + 2 < indicesEnd)
         {
             GetFace(faces, target, batchIndex, indices, indices + 1, indices + 2, positionData, normalData, skinningData,
@@ -801,11 +801,11 @@ void DecalSet::GetFace(Vector<PODVector<DecalVertex> >& faces, Drawable* target,
 {
     bool hasNormals = normalData != 0;
     bool hasSkinning = skinned_ && skinningData != 0;
-    
+
     const Vector3& v0 = *((const Vector3*)(&positionData[i0 * positionStride]));
     const Vector3& v1 = *((const Vector3*)(&positionData[i1 * positionStride]));
     const Vector3& v2 = *((const Vector3*)(&positionData[i2 * positionStride]));
-    
+
     // Calculate unsmoothed face normals if no normal data
     Vector3 faceNormal = Vector3::ZERO;
     if (!hasNormals)
@@ -814,19 +814,19 @@ void DecalSet::GetFace(Vector<PODVector<DecalVertex> >& faces, Drawable* target,
         Vector3 dist2 = v2 - v0;
         faceNormal = (dist1.CrossProduct(dist2)).Normalized();
     }
-    
+
     const Vector3& n0 = hasNormals ? *((const Vector3*)(&normalData[i0 * normalStride])) : faceNormal;
     const Vector3& n1 = hasNormals ? *((const Vector3*)(&normalData[i1 * normalStride])) : faceNormal;
     const Vector3& n2 = hasNormals ? *((const Vector3*)(&normalData[i2 * normalStride])) : faceNormal;
-    
+
     const unsigned char* s0 = hasSkinning ? &skinningData[i0 * skinningStride] : (const unsigned char*)0;
     const unsigned char* s1 = hasSkinning ? &skinningData[i1 * skinningStride] : (const unsigned char*)0;
     const unsigned char* s2 = hasSkinning ? &skinningData[i2 * skinningStride] : (const unsigned char*)0;
-    
+
     // Check if face is too much away from the decal normal
     if (decalNormal.DotProduct((n0 + n1 + n2) / 3.0f) < normalCutoff)
         return;
-    
+
     // Check if face is culled completely by any of the planes
     for (unsigned i = PLANE_FAR; i < NUM_FRUSTUM_PLANES; --i)
     {
@@ -834,7 +834,7 @@ void DecalSet::GetFace(Vector<PODVector<DecalVertex> >& faces, Drawable* target,
         if (plane.Distance(v0) < 0.0f && plane.Distance(v1) < 0.0f && plane.Distance(v2) < 0.0f)
             return;
     }
-    
+
     faces.Resize(faces.Size() + 1);
     PODVector<DecalVertex>& face = faces.Back();
     if (!hasSkinning)
@@ -855,12 +855,12 @@ void DecalSet::GetFace(Vector<PODVector<DecalVertex> >& faces, Drawable* target,
         unsigned char nbi0[4];
         unsigned char nbi1[4];
         unsigned char nbi2[4];
-        
+
         // Make sure all bones are found and that there is room in the skinning matrices
         if (!GetBones(target, batchIndex, bw0, bi0, nbi0) || !GetBones(target, batchIndex, bw1, bi1, nbi1) ||
             !GetBones(target, batchIndex, bw2, bi2, nbi2))
             return;
-        
+
         face.Reserve(3);
         face.Push(DecalVertex(v0, n0, bw0, nbi0));
         face.Push(DecalVertex(v1, n1, bw1, nbi1));
@@ -874,11 +874,11 @@ bool DecalSet::GetBones(Drawable* target, unsigned batchIndex, const float* blen
     AnimatedModel* animatedModel = dynamic_cast<AnimatedModel*>(target);
     if (!animatedModel)
         return false;
-    
+
     // Check whether target is using global or per-geometry skinning
     const Vector<PODVector<Matrix3x4> >& geometrySkinMatrices = animatedModel->GetGeometrySkinMatrices();
     const Vector<PODVector<unsigned> >& geometryBoneMappings = animatedModel->GetGeometryBoneMappings();
-    
+
     for (unsigned i = 0; i < 4; ++i)
     {
         if (blendWeights[i] > 0.0f)
@@ -888,16 +888,16 @@ bool DecalSet::GetBones(Drawable* target, unsigned batchIndex, const float* blen
                 bone = animatedModel->GetSkeleton().GetBone(blendIndices[i]);
             else if (blendIndices[i] < geometryBoneMappings[batchIndex].Size())
                 bone = animatedModel->GetSkeleton().GetBone(geometryBoneMappings[batchIndex][blendIndices[i]]);
-            
+
             if (!bone)
             {
                 LOGWARNING("Out of range bone index for skinned decal");
                 return false;
             }
-            
+
             bool found = false;
             unsigned index;
-            
+
             for (index = 0; index < bones_.Size(); ++index)
             {
                 if (bones_[index].node_ == bone->node_)
@@ -911,7 +911,7 @@ bool DecalSet::GetBones(Drawable* target, unsigned batchIndex, const float* blen
                     }
                 }
             }
-            
+
             if (!found)
             {
                 if (bones_.Size() >= MAX_SKIN_MATRICES)
@@ -927,18 +927,18 @@ bool DecalSet::GetBones(Drawable* target, unsigned batchIndex, const float* blen
                     bones_[index] = *bone;
                     skinMatrices_.Resize(skinMatrices_.Size() + 1);
                     skinningDirty_ = true;
-                    
+
                     // Start listening to bone transform changes to update skinning
                     bone->node_->AddListener(this);
                 }
             }
-            
+
             newBlendIndices[i] = index;
         }
         else
             newBlendIndices[i] = 0;
     }
-    
+
     // Update amount of shader data in the decal batch
     UpdateBatch();
     return true;
@@ -948,7 +948,7 @@ void DecalSet::CalculateUVs(Decal& decal, const Matrix3x4& view, const Matrix4&
     const Vector2& bottomRightUV)
 {
     Matrix4 viewProj = projection * view;
-    
+
     for (PODVector<DecalVertex>::Iterator i = decal.vertices_.Begin(); i != decal.vertices_.End(); ++i)
     {
         Vector3 projected = viewProj * i->position_;
@@ -991,7 +991,7 @@ void DecalSet::CalculateBoundingBox()
     boundingBox_.Clear();
     for (List<Decal>::ConstIterator i = decals_.Begin(); i != decals_.End(); ++i)
         boundingBox_.Merge(i->boundingBox_);
-    
+
     boundingBoxDirty_ = false;
 }
 
@@ -1000,7 +1000,7 @@ void DecalSet::UpdateBufferSize()
     vertexBuffer_->SetSize(maxVertices_, skinned_ ? SKINNED_ELEMENT_MASK : STATIC_ELEMENT_MASK);
     indexBuffer_->SetSize(maxIndices_, false);
     geometry_->SetVertexBuffer(0, vertexBuffer_);
-    
+
     bufferDirty_ = true;
     bufferSizeDirty_ = false;
 }
@@ -1008,14 +1008,14 @@ void DecalSet::UpdateBufferSize()
 void DecalSet::UpdateBuffers()
 {
     geometry_->SetDrawRange(TRIANGLE_LIST, 0, numIndices_, 0, numVertices_);
-    
+
     float* vertices = (float*)vertexBuffer_->Lock(0, numVertices_);
     unsigned short* indices = (unsigned short*)indexBuffer_->Lock(0, numIndices_);
-    
+
     if (vertices && indices)
     {
         unsigned short indexStart = 0;
-        
+
         for (List<Decal>::ConstIterator i = decals_.Begin(); i != decals_.End(); ++i)
         {
             for (unsigned j = 0; j < i->vertices_.Size(); ++j)
@@ -1042,14 +1042,14 @@ void DecalSet::UpdateBuffers()
                     *vertices++ = *((float*)vertex.blendIndices_);
                 }
             }
-            
+
             for (unsigned j = 0; j < i->indices_.Size(); ++j)
                 *indices++ = i->indices_[j] + indexStart;
-            
+
             indexStart += i->vertices_.Size();
         }
     }
-    
+
     vertexBuffer_->Unlock();
     vertexBuffer_->ClearDataLost();
     indexBuffer_->Unlock();
@@ -1061,7 +1061,7 @@ void DecalSet::UpdateSkinning()
 {
     // Use model's world transform in case a bone is missing
     const Matrix3x4& worldTransform = node_->GetWorldTransform();
-    
+
     for (unsigned i = 0; i < bones_.Size(); ++i)
     {
         const Bone& bone = bones_[i];
@@ -1070,7 +1070,7 @@ void DecalSet::UpdateSkinning()
         else
             skinMatrices_[i] = worldTransform;
     }
-    
+
     skinningDirty_ = false;
 }
 
@@ -1093,10 +1093,10 @@ void DecalSet::UpdateBatch()
 void DecalSet::AssignBoneNodes()
 {
     assignBonesPending_ = false;
-    
+
     if (!node_)
         return;
-    
+
     // Find the bone nodes from the node hierarchy and add listeners
     for (Vector<Bone>::Iterator i = bones_.Begin(); i != bones_.End(); ++i)
     {
@@ -1112,13 +1112,13 @@ void DecalSet::UpdateEventSubscription(bool checkAllDecals)
     Scene* scene = GetScene();
     if (!scene)
         return;
-    
+
     bool enabled = IsEnabledEffective();
-    
+
     if (enabled && checkAllDecals)
     {
         bool hasTimeLimitedDecals = false;
-        
+
         for (List<Decal>::ConstIterator i = decals_.Begin(); i != decals_.End(); ++i)
         {
             if (i->timeToLive_ > 0.0f)
@@ -1127,11 +1127,11 @@ void DecalSet::UpdateEventSubscription(bool checkAllDecals)
                 break;
             }
         }
-        
+
         // If no time limited decals, no need to subscribe to scene update
         enabled = hasTimeLimitedDecals;
     }
-    
+
     if (enabled && !subscribed_)
     {
         SubscribeToEvent(scene, E_SCENEPOSTUPDATE, HANDLER(DecalSet, HandleScenePostUpdate));
@@ -1147,13 +1147,13 @@ void DecalSet::UpdateEventSubscription(bool checkAllDecals)
 void DecalSet::HandleScenePostUpdate(StringHash eventType, VariantMap& eventData)
 {
     using namespace ScenePostUpdate;
-    
+
     float timeStep = eventData[P_TIMESTEP].GetFloat();
-    
+
     for (List<Decal>::Iterator i = decals_.Begin(); i != decals_.End();)
     {
         i->timer_ += timeStep;
-        
+
         // Remove the decal if time to live expired
         if (i->timeToLive_ > 0.0f && i->timer_ > i->timeToLive_)
             i = RemoveDecal(i);

+ 15 - 15
Source/Engine/Graphics/DecalSet.h

@@ -40,14 +40,14 @@ struct DecalVertex
     DecalVertex()
     {
     }
-    
+
     /// Construct with position and normal.
     DecalVertex(const Vector3& position, const Vector3& normal) :
         position_(position),
         normal_(normal)
     {
     }
-    
+
     // Construct with position, normal and skinning information.
     DecalVertex(const Vector3& position, const Vector3& normal, const float* blendWeights, const unsigned char* blendIndices) :
         position_(position),
@@ -59,7 +59,7 @@ struct DecalVertex
             blendIndices_[i] = blendIndices[i];
         }
     }
-    
+
     /// Position.
     Vector3 position_;
     /// Normal.
@@ -83,12 +83,12 @@ struct Decal
         timeToLive_(0.0f)
     {
     }
-    
+
     /// Add a vertex.
     void AddVertex(const DecalVertex& vertex);
     /// Calculate local-space bounding box.
     void CalculateBoundingBox();
-    
+
     /// Decal age timer.
     float timer_;
     /// Maximum time to live in seconds (0 = infinite)
@@ -105,7 +105,7 @@ struct Decal
 class URHO3D_API DecalSet : public Drawable
 {
     OBJECT(DecalSet);
-    
+
 public:
     /// Construct.
     DecalSet(Context* context);
@@ -113,7 +113,7 @@ public:
     virtual ~DecalSet();
     /// Register object factory.
     static void RegisterObject(Context* context);
-    
+
     /// Apply attribute changes that can not be applied immediately. Called after scene load or a network update.
     virtual void ApplyAttributes();
     /// Handle enabled/disabled state change.
@@ -126,7 +126,7 @@ public:
     virtual void UpdateGeometry(const FrameInfo& frame);
     /// Return whether a geometry update is necessary, and if it can happen in a worker thread.
     virtual UpdateGeometryType GetUpdateGeometryType();
-    
+
     /// Set material. The material should use a small negative depth bias to avoid Z-fighting.
     void SetMaterial(Material* material);
     /// Set maximum number of decal vertices.
@@ -139,7 +139,7 @@ public:
     void RemoveDecals(unsigned num);
     /// Remove all decals.
     void RemoveAllDecals();
-    
+
     /// Return material.
     Material* GetMaterial() const;
     /// Return number of decals.
@@ -152,22 +152,22 @@ public:
     unsigned GetMaxVertices() const { return maxVertices_; }
     /// Return maximum number of decal vertex indices.
     unsigned GetMaxIndices() const { return maxIndices_; }
-    
+
     /// Set material attribute.
-    void SetMaterialAttr(ResourceRef value);
+    void SetMaterialAttr(const ResourceRef& value);
     /// Set decals attribute.
-    void SetDecalsAttr(PODVector<unsigned char> value);
+    void SetDecalsAttr(const PODVector<unsigned char>& value);
     /// Return material attribute.
     ResourceRef GetMaterialAttr() const;
     /// Return decals attribute.
     PODVector<unsigned char> GetDecalsAttr() const;
-    
+
 protected:
     /// Recalculate the world-space bounding box.
     virtual void OnWorldBoundingBoxUpdate();
     /// Handle node transform being dirtied.
     virtual void OnMarkedDirty(Node* node);
-    
+
 private:
     /// Get triangle faces from the target geometry.
     void GetFaces(Vector<PODVector<DecalVertex> >& faces, Drawable* target, unsigned batchIndex, const Frustum& frustum, const Vector3& decalNormal, float normalCutoff);
@@ -199,7 +199,7 @@ private:
     void UpdateEventSubscription(bool checkAllDecals);
     /// Handle scene post-update event.
     void HandleScenePostUpdate(StringHash eventType, VariantMap& eventData);
-    
+
     /// Geometry.
     SharedPtr<Geometry> geometry_;
     /// Vertex buffer.

+ 5 - 5
Source/Engine/Graphics/Drawable.cpp

@@ -91,11 +91,11 @@ Drawable::~Drawable()
 
 void Drawable::RegisterObject(Context* context)
 {
-    ATTRIBUTE(Drawable, VAR_INT, "Max Lights", maxLights_, 0, AM_DEFAULT);
-    ATTRIBUTE(Drawable, VAR_INT, "View Mask", viewMask_, DEFAULT_VIEWMASK, AM_DEFAULT);
-    ATTRIBUTE(Drawable, VAR_INT, "Light Mask", lightMask_, DEFAULT_LIGHTMASK, AM_DEFAULT);
-    ATTRIBUTE(Drawable, VAR_INT, "Shadow Mask", shadowMask_, DEFAULT_SHADOWMASK, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Drawable, VAR_INT, "Zone Mask", GetZoneMask, SetZoneMask, unsigned, DEFAULT_ZONEMASK, AM_DEFAULT);
+    ATTRIBUTE("Max Lights", int, maxLights_, 0, AM_DEFAULT);
+    ATTRIBUTE("View Mask", int, viewMask_, DEFAULT_VIEWMASK, AM_DEFAULT);
+    ATTRIBUTE("Light Mask", int, lightMask_, DEFAULT_LIGHTMASK, AM_DEFAULT);
+    ATTRIBUTE("Shadow Mask", int, shadowMask_, DEFAULT_SHADOWMASK, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Zone Mask", GetZoneMask, SetZoneMask, unsigned, DEFAULT_ZONEMASK, AM_DEFAULT);
 }
 
 void Drawable::OnSetEnabled()

+ 39 - 44
Source/Engine/Graphics/Light.cpp

@@ -81,11 +81,6 @@ void FocusParameters::Validate()
     minView_ = Max(minView_, SHADOW_MIN_VIEW);
 }
 
-template<> LightType Variant::Get<LightType>() const
-{
-    return (LightType)GetInt();
-}
-
 Light::Light(Context* context) :
     Drawable(context, DRAWABLE_LIGHT),
     lightType_(DEFAULT_LIGHTTYPE),
@@ -115,38 +110,38 @@ void Light::RegisterObject(Context* context)
 {
     context->RegisterFactory<Light>(SCENE_CATEGORY);
 
-    ACCESSOR_ATTRIBUTE(Light, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
-    ENUM_ACCESSOR_ATTRIBUTE(Light, "Light Type", GetLightType, SetLightType, LightType, typeNames, DEFAULT_LIGHTTYPE, AM_DEFAULT);
-    REF_ACCESSOR_ATTRIBUTE(Light, VAR_COLOR, "Color", GetColor, SetColor, Color, Color::WHITE, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Specular Intensity", GetSpecularIntensity, SetSpecularIntensity, float, DEFAULT_SPECULARINTENSITY, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Brightness Multiplier", GetBrightness, SetBrightness, float, DEFAULT_BRIGHTNESS, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Range", GetRange, SetRange, float, DEFAULT_RANGE, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Spot FOV", GetFov, SetFov, float, DEFAULT_LIGHT_FOV, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Spot Aspect Ratio", GetAspectRatio, SetAspectRatio, float, 1.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Light, VAR_RESOURCEREF, "Attenuation Texture", GetRampTextureAttr, SetRampTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Light, VAR_RESOURCEREF, "Light Shape Texture", GetShapeTextureAttr, SetShapeTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Light, VAR_BOOL, "Can Be Occluded", IsOccludee, SetOccludee, bool, true, AM_DEFAULT);
-    ATTRIBUTE(Light, VAR_BOOL, "Cast Shadows", castShadows_, false, AM_DEFAULT);
-    ATTRIBUTE(Light, VAR_BOOL, "Per Vertex", perVertex_, false, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Draw Distance", GetDrawDistance, SetDrawDistance, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Fade Distance", GetFadeDistance, SetFadeDistance, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Shadow Distance", GetShadowDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Shadow Fade Distance", GetShadowFadeDistance, SetShadowFadeDistance, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Shadow Intensity", GetShadowIntensity, SetShadowIntensity, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Shadow Resolution", GetShadowResolution, SetShadowResolution, float, 1.0f, AM_DEFAULT);
-    ATTRIBUTE(Light, VAR_BOOL, "Focus To Scene", shadowFocus_.focus_, true, AM_DEFAULT);
-    ATTRIBUTE(Light, VAR_BOOL, "Non-uniform View", shadowFocus_.nonUniform_, true, AM_DEFAULT);
-    ATTRIBUTE(Light, VAR_BOOL, "Auto-Reduce Size", shadowFocus_.autoSize_, true, AM_DEFAULT);
-    ATTRIBUTE(Light, VAR_VECTOR4, "CSM Splits", shadowCascade_.splits_, Vector4(DEFAULT_SHADOWSPLIT, 0.0f, 0.0f, 0.0f), AM_DEFAULT);
-    ATTRIBUTE(Light, VAR_FLOAT, "CSM Fade Start", shadowCascade_.fadeStart_, DEFAULT_SHADOWFADESTART, AM_DEFAULT);
-    ATTRIBUTE(Light, VAR_FLOAT, "CSM Bias Auto Adjust", shadowCascade_.biasAutoAdjust_, DEFAULT_BIASAUTOADJUST, AM_DEFAULT);
-    ATTRIBUTE(Light, VAR_FLOAT, "View Size Quantize", shadowFocus_.quantize_, DEFAULT_SHADOWQUANTIZE, AM_DEFAULT);
-    ATTRIBUTE(Light, VAR_FLOAT, "View Size Minimum", shadowFocus_.minView_, DEFAULT_SHADOWMINVIEW, AM_DEFAULT);
-    ATTRIBUTE(Light, VAR_FLOAT, "Depth Constant Bias", shadowBias_.constantBias_, DEFAULT_CONSTANTBIAS, AM_DEFAULT);
-    ATTRIBUTE(Light, VAR_FLOAT, "Depth Slope Bias", shadowBias_.slopeScaledBias_, DEFAULT_SLOPESCALEDBIAS, AM_DEFAULT);
-    ATTRIBUTE(Light, VAR_FLOAT, "Near/Farclip Ratio", shadowNearFarRatio_, DEFAULT_SHADOWNEARFARRATIO, AM_DEFAULT);
-    ATTRIBUTE(Light, VAR_INT, "View Mask", viewMask_, DEFAULT_VIEWMASK, AM_DEFAULT);
-    ATTRIBUTE(Light, VAR_INT, "Light Mask", lightMask_, DEFAULT_LIGHTMASK, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
+    ENUM_ACCESSOR_ATTRIBUTE("Light Type", GetLightType, SetLightType, LightType, typeNames, DEFAULT_LIGHTTYPE, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Color", GetColor, SetColor, Color, Color::WHITE, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Specular Intensity", GetSpecularIntensity, SetSpecularIntensity, float, DEFAULT_SPECULARINTENSITY, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Brightness Multiplier", GetBrightness, SetBrightness, float, DEFAULT_BRIGHTNESS, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Range", GetRange, SetRange, float, DEFAULT_RANGE, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Spot FOV", GetFov, SetFov, float, DEFAULT_LIGHT_FOV, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Spot Aspect Ratio", GetAspectRatio, SetAspectRatio, float, 1.0f, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Attenuation Texture", GetRampTextureAttr, SetRampTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Light Shape Texture", GetShapeTextureAttr, SetShapeTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Can Be Occluded", IsOccludee, SetOccludee, bool, true, AM_DEFAULT);
+    ATTRIBUTE("Cast Shadows", bool, castShadows_, false, AM_DEFAULT);
+    ATTRIBUTE("Per Vertex", bool, perVertex_, false, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Draw Distance", GetDrawDistance, SetDrawDistance, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Fade Distance", GetFadeDistance, SetFadeDistance, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Shadow Distance", GetShadowDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Shadow Fade Distance", GetShadowFadeDistance, SetShadowFadeDistance, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Shadow Intensity", GetShadowIntensity, SetShadowIntensity, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Shadow Resolution", GetShadowResolution, SetShadowResolution, float, 1.0f, AM_DEFAULT);
+    ATTRIBUTE("Focus To Scene", bool, shadowFocus_.focus_, true, AM_DEFAULT);
+    ATTRIBUTE("Non-uniform View", bool, shadowFocus_.nonUniform_, true, AM_DEFAULT);
+    ATTRIBUTE("Auto-Reduce Size", bool, shadowFocus_.autoSize_, true, AM_DEFAULT);
+    ATTRIBUTE("CSM Splits", Vector4, shadowCascade_.splits_, Vector4(DEFAULT_SHADOWSPLIT, 0.0f, 0.0f, 0.0f), AM_DEFAULT);
+    ATTRIBUTE("CSM Fade Start", float, shadowCascade_.fadeStart_, DEFAULT_SHADOWFADESTART, AM_DEFAULT);
+    ATTRIBUTE("CSM Bias Auto Adjust", float, shadowCascade_.biasAutoAdjust_, DEFAULT_BIASAUTOADJUST, AM_DEFAULT);
+    ATTRIBUTE("View Size Quantize", float, shadowFocus_.quantize_, DEFAULT_SHADOWQUANTIZE, AM_DEFAULT);
+    ATTRIBUTE("View Size Minimum", float, shadowFocus_.minView_, DEFAULT_SHADOWMINVIEW, AM_DEFAULT);
+    ATTRIBUTE("Depth Constant Bias", float, shadowBias_.constantBias_, DEFAULT_CONSTANTBIAS, AM_DEFAULT);
+    ATTRIBUTE("Depth Slope Bias", float, shadowBias_.slopeScaledBias_, DEFAULT_SLOPESCALEDBIAS, AM_DEFAULT);
+    ATTRIBUTE("Near/Farclip Ratio", float, shadowNearFarRatio_, DEFAULT_SHADOWNEARFARRATIO, AM_DEFAULT);
+    ATTRIBUTE("View Mask", int, viewMask_, DEFAULT_VIEWMASK, AM_DEFAULT);
+    ATTRIBUTE("Light Mask", int, lightMask_, DEFAULT_LIGHTMASK, AM_DEFAULT);
 }
 
 void Light::OnSetAttribute(const AttributeInfo& attr, const Variant& src)
@@ -230,7 +225,7 @@ void Light::UpdateBatches(const FrameInfo& frame)
 void Light::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
 {
     Color color = GetEffectiveColor();
-    
+
     if (debug && IsEnabledEffective())
     {
         switch (lightType_)
@@ -390,7 +385,7 @@ Frustum Light::GetFrustum() const
 int Light::GetNumShadowSplits() const
 {
     int ret = 1;
-    
+
     if (shadowCascade_.splits_[1] > shadowCascade_.splits_[0])
     {
         ++ret;
@@ -401,7 +396,7 @@ int Light::GetNumShadowSplits() const
                 ++ret;
         }
     }
-    
+
     ret = Min(ret, MAX_CASCADE_SPLITS);
     // Shader Model 2 can only support 3 splits max. due to pixel shader instruction count limits
     if (ret == 4)
@@ -410,7 +405,7 @@ int Light::GetNumShadowSplits() const
         if (graphics && !graphics->GetSM3Support())
             --ret;
     }
-    
+
     return ret;
 }
 
@@ -441,7 +436,7 @@ const Matrix3x4& Light::GetVolumeTransform(Camera* camera)
 {
     if (!node_)
         return Matrix3x4::IDENTITY;
-    
+
     switch (lightType_)
     {
     case LIGHT_DIRECTIONAL:
@@ -464,13 +459,13 @@ const Matrix3x4& Light::GetVolumeTransform(Camera* camera)
     return volumeTransform_;
 }
 
-void Light::SetRampTextureAttr(ResourceRef value)
+void Light::SetRampTextureAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     rampTexture_ = static_cast<Texture*>(cache->GetResource(value.type_, value.name_));
 }
 
-void Light::SetShapeTextureAttr(ResourceRef value)
+void Light::SetShapeTextureAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     shapeTexture_ = static_cast<Texture*>(cache->GetResource(value.type_, value.name_));

+ 21 - 21
Source/Engine/Graphics/Light.h

@@ -57,17 +57,17 @@ struct URHO3D_API BiasParameters
     BiasParameters()
     {
     }
-    
+
     /// Construct with initial values.
     BiasParameters(float constantBias, float slopeScaledBias) :
         constantBias_(constantBias),
         slopeScaledBias_(slopeScaledBias)
     {
     }
-    
+
     /// Validate parameters.
     void Validate();
-    
+
     /// Constant bias.
     float constantBias_;
     /// Slope scaled bias.
@@ -81,7 +81,7 @@ struct URHO3D_API CascadeParameters
     CascadeParameters()
     {
     }
-    
+
     /// Construct with initial values.
     CascadeParameters(float split1, float split2, float split3, float split4, float fadeStart, float biasAutoAdjust = 1.0f) :
         fadeStart_(fadeStart),
@@ -92,20 +92,20 @@ struct URHO3D_API CascadeParameters
         splits_[2] = split3;
         splits_[3] = split4;
     }
-    
+
     /// Validate parameters.
     void Validate();
-    
+
     /// Return shadow maximum range.
     float GetShadowRange() const
     {
         float ret = 0.0f;
         for (unsigned i = 0; i < MAX_CASCADE_SPLITS; ++i)
             ret = Max(ret, splits_[i]);
-        
+
         return ret;
     }
-    
+
     /// Far clip values of the splits.
     float splits_[4];
     /// The point relative to the total shadow range where shadow fade begins (0.0 - 1.0)
@@ -121,7 +121,7 @@ struct URHO3D_API FocusParameters
     FocusParameters()
     {
     }
-    
+
     /// Construct with initial values.
     FocusParameters(bool focus, bool nonUniform, bool autoSize, float quantize, float minView) :
         focus_(focus),
@@ -131,10 +131,10 @@ struct URHO3D_API FocusParameters
         minView_(minView)
     {
     }
-    
+
     /// Validate parameters.
     void Validate();
-    
+
     /// Focus flag.
     bool focus_;
     /// Non-uniform focusing flag.
@@ -151,7 +151,7 @@ struct URHO3D_API FocusParameters
 class URHO3D_API Light : public Drawable
 {
     OBJECT(Light);
-    
+
 public:
     /// Construct.
     Light(Context* context);
@@ -159,7 +159,7 @@ public:
     virtual ~Light();
     /// Register object factory. Drawable must be registered first.
     static void RegisterObject(Context* context);
-    
+
     /// Handle attribute change.
     virtual void OnSetAttribute(const AttributeInfo& attr, const Variant& src);
     /// Process octree raycast. May be called from a worker thread.
@@ -168,7 +168,7 @@ public:
     virtual void UpdateBatches(const FrameInfo& frame);
     /// Visualize the component as debug geometry.
     virtual void DrawDebugGeometry(DebugRenderer* debug, bool depthTest);
-    
+
     /// Set light type.
     void SetLightType(LightType type);
     /// Set vertex lighting mode.
@@ -205,7 +205,7 @@ public:
     void SetRampTexture(Texture* texture);
     /// Set spotlight attenuation texture.
     void SetShapeTexture(Texture* texture);
-    
+
     /// Return light type.
     LightType GetLightType() const { return lightType_; }
     /// Return vertex lighting mode.
@@ -252,7 +252,7 @@ public:
     int GetNumShadowSplits() const;
     /// Return whether light has negative (darkening) color.
     bool IsNegative() const { return GetEffectiveColor().SumRGB() < 0.0f; }
-    
+
     /// Set sort value based on intensity and view distance.
     void SetIntensitySortValue(float distance);
     /// Set sort value based on overall intensity over a bounding box.
@@ -267,20 +267,20 @@ public:
     LightBatchQueue* GetLightQueue() const { return lightQueue_; }
     /// Return a divisor value based on intensity for calculating the sort value.
     float GetIntensityDivisor(float attenuation = 1.0f) const { return Max(GetEffectiveColor().SumRGB(), 0.0f) * attenuation + M_EPSILON; }
-    
+
     /// Set ramp texture attribute.
-    void SetRampTextureAttr(ResourceRef value);
+    void SetRampTextureAttr(const ResourceRef& value);
     /// Set shape texture attribute.
-    void SetShapeTextureAttr(ResourceRef value);
+    void SetShapeTextureAttr(const ResourceRef& value);
     /// Return ramp texture attribute.
     ResourceRef GetRampTextureAttr() const;
     /// Return shape texture attribute.
     ResourceRef GetShapeTextureAttr() const;
-    
+
 protected:
     /// Recalculate the world-space bounding box.
     virtual void OnWorldBoundingBoxUpdate();
-    
+
 private:
     /// Light type.
     LightType lightType_;

+ 3 - 3
Source/Engine/Graphics/Octree.cpp

@@ -359,9 +359,9 @@ void Octree::RegisterObject(Context* context)
     Vector3 defaultBoundsMin = -Vector3::ONE * DEFAULT_OCTREE_SIZE;
     Vector3 defaultBoundsMax = Vector3::ONE * DEFAULT_OCTREE_SIZE;
 
-    ATTRIBUTE(Octree, VAR_VECTOR3, "Bounding Box Min", worldBoundingBox_.min_, defaultBoundsMin, AM_DEFAULT);
-    ATTRIBUTE(Octree, VAR_VECTOR3, "Bounding Box Max", worldBoundingBox_.max_, defaultBoundsMax, AM_DEFAULT);
-    ATTRIBUTE(Octree, VAR_INT, "Number of Levels", numLevels_, DEFAULT_OCTREE_LEVELS, AM_DEFAULT);
+    ATTRIBUTE("Bounding Box Min", Vector3, worldBoundingBox_.min_, defaultBoundsMin, AM_DEFAULT);
+    ATTRIBUTE("Bounding Box Max", Vector3, worldBoundingBox_.max_, defaultBoundsMax, AM_DEFAULT);
+    ATTRIBUTE("Number of Levels", int, numLevels_, DEFAULT_OCTREE_LEVELS, AM_DEFAULT);
 }
 
 void Octree::OnSetAttribute(const AttributeInfo& attr, const Variant& src)

+ 26 - 26
Source/Engine/Graphics/ParticleEmitter.cpp

@@ -58,21 +58,21 @@ void ParticleEmitter::RegisterObject(Context* context)
 {
     context->RegisterFactory<ParticleEmitter>(GEOMETRY_CATEGORY);
 
-    ACCESSOR_ATTRIBUTE(ParticleEmitter, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(ParticleEmitter, VAR_RESOURCEREF, "Effect", GetEffectAttr, SetEffectAttr, ResourceRef, ResourceRef(ParticleEffect::GetTypeStatic()), AM_DEFAULT);
-    ENUM_ATTRIBUTE(ParticleEmitter, "Face Camera Mode", faceCameraMode_, faceCameraModeNames, FC_ROTATE_XYZ, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(ParticleEmitter, VAR_BOOL, "Can Be Occluded", IsOccludee, SetOccludee, bool, true, AM_DEFAULT);
-    ATTRIBUTE(ParticleEmitter, VAR_BOOL, "Cast Shadows", castShadows_, false, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(ParticleEmitter, VAR_FLOAT, "Draw Distance", GetDrawDistance, SetDrawDistance, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(ParticleEmitter, VAR_FLOAT, "Shadow Distance", GetShadowDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(ParticleEmitter, VAR_FLOAT, "Animation LOD Bias", GetAnimationLodBias, SetAnimationLodBias, float, 1.0f, AM_DEFAULT);
-    ATTRIBUTE(ParticleEmitter, VAR_BOOL, "Is Emitting", emitting_, true, AM_FILE);
-    ATTRIBUTE(ParticleEmitter, VAR_FLOAT, "Period Timer", periodTimer_, 0.0f, AM_FILE | AM_NOEDIT);
-    ATTRIBUTE(ParticleEmitter, VAR_FLOAT, "Emission Timer", emissionTimer_, 0.0f, AM_FILE | AM_NOEDIT);
-    COPY_BASE_ATTRIBUTES(ParticleEmitter, Drawable);
-    ACCESSOR_ATTRIBUTE(ParticleEmitter, VAR_VARIANTVECTOR, "Particles", GetParticlesAttr, SetParticlesAttr, VariantVector, Variant::emptyVariantVector, AM_FILE | AM_NOEDIT);
-    ACCESSOR_ATTRIBUTE(ParticleEmitter, VAR_VARIANTVECTOR, "Billboards", GetParticleBillboardsAttr, SetBillboardsAttr, VariantVector, Variant::emptyVariantVector, AM_FILE | AM_NOEDIT);
-    ATTRIBUTE(ParticleEmitter, VAR_BOOL, "Serialize Particles", serializeParticles_, true, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Effect", GetEffectAttr, SetEffectAttr, ResourceRef, ResourceRef(ParticleEffect::GetTypeStatic()), AM_DEFAULT);
+    ENUM_ATTRIBUTE("Face Camera Mode", faceCameraMode_, faceCameraModeNames, FC_ROTATE_XYZ, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Can Be Occluded", IsOccludee, SetOccludee, bool, true, AM_DEFAULT);
+    ATTRIBUTE("Cast Shadows", bool, castShadows_, false, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Draw Distance", GetDrawDistance, SetDrawDistance, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Shadow Distance", GetShadowDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Animation LOD Bias", GetAnimationLodBias, SetAnimationLodBias, float, 1.0f, AM_DEFAULT);
+    ATTRIBUTE("Is Emitting", bool, emitting_, true, AM_FILE);
+    ATTRIBUTE("Period Timer", float, periodTimer_, 0.0f, AM_FILE | AM_NOEDIT);
+    ATTRIBUTE("Emission Timer", float, emissionTimer_, 0.0f, AM_FILE | AM_NOEDIT);
+    COPY_BASE_ATTRIBUTES(Drawable);
+    MIXED_ACCESSOR_ATTRIBUTE("Particles", GetParticlesAttr, SetParticlesAttr, VariantVector, Variant::emptyVariantVector, AM_FILE | AM_NOEDIT);
+    MIXED_ACCESSOR_ATTRIBUTE("Billboards", GetParticleBillboardsAttr, SetBillboardsAttr, VariantVector, Variant::emptyVariantVector, AM_FILE | AM_NOEDIT);
+    ATTRIBUTE("Serialize Particles", bool, serializeParticles_, true, AM_FILE);
 }
 
 void ParticleEmitter::OnSetEnabled()
@@ -188,7 +188,7 @@ void ParticleEmitter::Update(const FrameInfo& frame)
                 else
                     particle.velocity_ += lastTimeStep_ * constantForce;
             }
-            
+
             float dampingForce = effect_->GetDampingForce();
             if (dampingForce != 0.0f)
             {
@@ -262,7 +262,7 @@ void ParticleEmitter::SetEffect(ParticleEffect* effect)
 
     if (effect_)
         SubscribeToEvent(effect_, E_RELOADFINISHED, HANDLER(ParticleEmitter, HandleEffectReloadFinished));
-    
+
     ApplyEffect();
     MarkNetworkUpdate();
 }
@@ -319,7 +319,7 @@ void ParticleEmitter::ApplyEffect()
 {
     if (!effect_)
         return;
-    
+
     SetMaterial(effect_->GetMaterial());
     SetNumParticles(effect_->GetNumParticles());
     SetRelative(effect_->IsRelative());
@@ -328,7 +328,7 @@ void ParticleEmitter::ApplyEffect()
     SetAnimationLodBias(effect_->GetAnimationLodBias());
 }
 
-void ParticleEmitter::SetEffectAttr(ResourceRef value)
+void ParticleEmitter::SetEffectAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SetEffect(cache->GetResource<ParticleEffect>(value.name_));
@@ -339,11 +339,11 @@ ResourceRef ParticleEmitter::GetEffectAttr() const
     return GetResourceRef(effect_, ParticleEffect::GetTypeStatic());
 }
 
-void ParticleEmitter::SetParticlesAttr(VariantVector value)
+void ParticleEmitter::SetParticlesAttr(const VariantVector& value)
 {
     unsigned index = 0;
     SetNumParticles(index < value.Size() ? value[index++].GetUInt() : 0);
-    
+
     for (PODVector<Particle>::Iterator i = particles_.Begin(); i != particles_.End() && index < value.Size(); ++i)
     {
         i->velocity_ = value[index++].GetVector3();
@@ -365,7 +365,7 @@ VariantVector ParticleEmitter::GetParticlesAttr() const
         ret.Push(particles_.Size());
         return ret;
     }
-    
+
     ret.Reserve(particles_.Size() * 8 + 1);
     ret.Push(particles_.Size());
     for (PODVector<Particle>::ConstIterator i = particles_.Begin(); i != particles_.End(); ++i)
@@ -390,10 +390,10 @@ VariantVector ParticleEmitter::GetParticleBillboardsAttr() const
         ret.Push(billboards_.Size());
         return ret;
     }
-    
+
     ret.Reserve(billboards_.Size() * 6 + 1);
     ret.Push(billboards_.Size());
-    
+
     for (PODVector<Billboard>::ConstIterator i = billboards_.Begin(); i != billboards_.End(); ++i)
     {
         ret.Push(i->position_);
@@ -403,7 +403,7 @@ VariantVector ParticleEmitter::GetParticleBillboardsAttr() const
         ret.Push(i->rotation_);
         ret.Push(i->enabled_);
     }
-    
+
     return ret;
 }
 
@@ -431,7 +431,7 @@ bool ParticleEmitter::EmitNewParticle()
     Vector3 startPos;
     Vector3 startDir;
 
-    
+
     switch (effect_->GetEmitterType())
     {
     case EMITTER_SPHERE:

+ 3 - 3
Source/Engine/Graphics/ParticleEmitter.h

@@ -95,16 +95,16 @@ public:
     bool GetSerializeParticles() const { return serializeParticles_; }
 
     /// Set particles effect attribute.
-    void SetEffectAttr(ResourceRef value);
+    void SetEffectAttr(const ResourceRef& value);
     /// Set particles effect attribute.
     ResourceRef GetEffectAttr() const;
     /// Set particles attribute.
-    void SetParticlesAttr(VariantVector value);
+    void SetParticlesAttr(const VariantVector& value);
     /// Return particles attribute. Returns particle amount only if particles are not to be serialized.
     VariantVector GetParticlesAttr() const;
     /// Return billboards attribute. Returns billboard amount only if particles are not to be serialized.
     VariantVector GetParticleBillboardsAttr() const;
-    
+
 protected:
     /// Handle node being assigned.
     virtual void OnNodeSet(Node* node);

+ 1 - 1
Source/Engine/Graphics/Skybox.cpp

@@ -48,7 +48,7 @@ void Skybox::RegisterObject(Context* context)
 {
     context->RegisterFactory<Skybox>(GEOMETRY_CATEGORY);
 
-    COPY_BASE_ATTRIBUTES(Skybox, StaticModel);
+    COPY_BASE_ATTRIBUTES(StaticModel);
 }
 
 void Skybox::ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQueryResult>& results)

+ 51 - 51
Source/Engine/Graphics/StaticModel.cpp

@@ -57,41 +57,41 @@ StaticModel::~StaticModel()
 void StaticModel::RegisterObject(Context* context)
 {
     context->RegisterFactory<StaticModel>(GEOMETRY_CATEGORY);
-    
-    ACCESSOR_ATTRIBUTE(StaticModel, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(StaticModel, VAR_RESOURCEREF, "Model", GetModelAttr, SetModelAttr, ResourceRef, ResourceRef(Model::GetTypeStatic()), AM_DEFAULT);
-    REF_ACCESSOR_ATTRIBUTE(StaticModel, VAR_RESOURCEREFLIST, "Material", GetMaterialsAttr, SetMaterialsAttr, ResourceRefList, ResourceRefList(Material::GetTypeStatic()), AM_DEFAULT);
-    ATTRIBUTE(StaticModel, VAR_BOOL, "Is Occluder", occluder_, false, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(StaticModel, VAR_BOOL, "Can Be Occluded", IsOccludee, SetOccludee, bool, true, AM_DEFAULT);
-    ATTRIBUTE(StaticModel, VAR_BOOL, "Cast Shadows", castShadows_, false, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(StaticModel, VAR_FLOAT, "Draw Distance", GetDrawDistance, SetDrawDistance, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(StaticModel, VAR_FLOAT, "Shadow Distance", GetShadowDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(StaticModel, VAR_FLOAT, "LOD Bias", GetLodBias, SetLodBias, float, 1.0f, AM_DEFAULT);
-    COPY_BASE_ATTRIBUTES(StaticModel, Drawable);
-    ATTRIBUTE(StaticModel, VAR_INT, "Occlusion LOD Level", occlusionLodLevel_, M_MAX_UNSIGNED, AM_DEFAULT);
+
+    ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Model", GetModelAttr, SetModelAttr, ResourceRef, ResourceRef(Model::GetTypeStatic()), AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Material", GetMaterialsAttr, SetMaterialsAttr, ResourceRefList, ResourceRefList(Material::GetTypeStatic()), AM_DEFAULT);
+    ATTRIBUTE("Is Occluder", bool, occluder_, false, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Can Be Occluded", IsOccludee, SetOccludee, bool, true, AM_DEFAULT);
+    ATTRIBUTE("Cast Shadows", bool, castShadows_, false, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Draw Distance", GetDrawDistance, SetDrawDistance, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Shadow Distance", GetShadowDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("LOD Bias", GetLodBias, SetLodBias, float, 1.0f, AM_DEFAULT);
+    COPY_BASE_ATTRIBUTES(Drawable);
+    ATTRIBUTE("Occlusion LOD Level", int, occlusionLodLevel_, M_MAX_UNSIGNED, AM_DEFAULT);
 }
 
 void StaticModel::ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQueryResult>& results)
 {
     RayQueryLevel level = query.level_;
-    
+
     switch (level)
     {
     case RAY_AABB:
         Drawable::ProcessRayQuery(query, results);
         break;
-        
+
     case RAY_OBB:
     case RAY_TRIANGLE:
         Matrix3x4 inverse(node_->GetWorldTransform().Inverse());
         Ray localRay = query.ray_.Transformed(inverse);
         float distance = localRay.HitDistance(boundingBox_);
         Vector3 normal = -query.ray_.direction_;
-        
+
         if (level == RAY_TRIANGLE && distance < query.maxDistance_)
         {
             distance = M_INFINITY;
-            
+
             for (unsigned i = 0; i < batches_.Size(); ++i)
             {
                 Geometry* geometry = batches_[i].geometry_;
@@ -107,7 +107,7 @@ void StaticModel::ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQuer
                 }
             }
         }
-        
+
         if (distance < query.maxDistance_)
         {
             RayQueryResult result;
@@ -128,7 +128,7 @@ void StaticModel::UpdateBatches(const FrameInfo& frame)
     const BoundingBox& worldBoundingBox = GetWorldBoundingBox();
     const Matrix3x4& worldTransform = node_->GetWorldTransform();
     distance_ = frame.camera_->GetDistance(worldBoundingBox.Center());
-    
+
     if (batches_.Size() > 1)
     {
         for (unsigned i = 0; i < batches_.Size(); ++i)
@@ -142,10 +142,10 @@ void StaticModel::UpdateBatches(const FrameInfo& frame)
         batches_[0].distance_ = distance_;
         batches_[0].worldTransform_ = &worldTransform;
     }
-    
+
     float scale = worldBoundingBox.Size().DotProduct(DOT_SCALE);
     float newLodDistance = frame.camera_->GetLodDistance(distance_, scale, lodBias_);
-    
+
     if (newLodDistance != lodDistance_)
     {
         lodDistance_ = newLodDistance;
@@ -157,7 +157,7 @@ Geometry* StaticModel::GetLodGeometry(unsigned batchIndex, unsigned level)
 {
     if (batchIndex >= geometries_.Size())
         return 0;
-    
+
     // If level is out of range, use visible geometry
     if (level < geometries_[batchIndex].Size())
         return geometries_[batchIndex][level];
@@ -168,21 +168,21 @@ Geometry* StaticModel::GetLodGeometry(unsigned batchIndex, unsigned level)
 unsigned StaticModel::GetNumOccluderTriangles()
 {
     unsigned triangles = 0;
-    
+
     for (unsigned i = 0; i < batches_.Size(); ++i)
     {
         Geometry* geometry = GetLodGeometry(i, occlusionLodLevel_);
         if (!geometry)
             continue;
-        
+
         // Check that the material is suitable for occlusion (default material always is)
         Material* mat = batches_[i].material_;
         if (mat && !mat->GetOcclusion())
             continue;
-        
+
         triangles += geometry->GetIndexCount() / 3;
     }
-    
+
     return triangles;
 }
 
@@ -193,7 +193,7 @@ bool StaticModel::DrawOcclusion(OcclusionBuffer* buffer)
         Geometry* geometry = GetLodGeometry(i, occlusionLodLevel_);
         if (!geometry)
             continue;
-        
+
         // Check that the material is suitable for occlusion (default material always is) and set culling mode
         Material* material = batches_[i].material_;
         if (material)
@@ -204,26 +204,26 @@ bool StaticModel::DrawOcclusion(OcclusionBuffer* buffer)
         }
         else
             buffer->SetCullMode(CULL_CCW);
-        
+
         const unsigned char* vertexData;
         unsigned vertexSize;
         const unsigned char* indexData;
         unsigned indexSize;
         unsigned elementMask;
-        
+
         geometry->GetRawData(vertexData, vertexSize, indexData, indexSize, elementMask);
         // Check for valid geometry data
         if (!vertexData || !indexData)
             continue;
-        
+
         unsigned indexStart = geometry->GetIndexStart();
         unsigned indexCount = geometry->GetIndexCount();
-        
+
         // Draw and check for running out of triangles
         if (!buffer->Draw(node_->GetWorldTransform(), vertexData, vertexSize, indexData, indexSize, indexStart, indexCount))
             return false;
     }
-    
+
     return true;
 }
 
@@ -231,7 +231,7 @@ void StaticModel::SetModel(Model* model)
 {
     if (model == model_)
         return;
-    
+
     // If script erroneously calls StaticModel::SetModel on an AnimatedModel, warn and redirect
     if (GetType() == AnimatedModel::GetTypeStatic())
     {
@@ -240,13 +240,13 @@ void StaticModel::SetModel(Model* model)
         animatedModel->SetModel(model);
         return;
     }
-    
+
     // Unsubscribe from the reload event of previous model (if any), then subscribe to the new
     if (model_)
         UnsubscribeFromEvent(model_, E_RELOADFINISHED);
-    
+
     model_ = model;
-    
+
     if (model)
     {
         SubscribeToEvent(model, E_RELOADFINISHED, HANDLER(StaticModel, HandleModelReloadFinished));
@@ -269,7 +269,7 @@ void StaticModel::SetModel(Model* model)
         SetNumGeometries(0);
         SetBoundingBox(BoundingBox());
     }
-    
+
     MarkNetworkUpdate();
 }
 
@@ -277,7 +277,7 @@ void StaticModel::SetMaterial(Material* material)
 {
     for (unsigned i = 0; i < batches_.Size(); ++i)
         batches_[i].material_ = material;
-    
+
     MarkNetworkUpdate();
 }
 
@@ -288,7 +288,7 @@ bool StaticModel::SetMaterial(unsigned index, Material* material)
         LOGERROR("Material index out of bounds");
         return false;
     }
-    
+
     batches_[index].material_ = material;
     MarkNetworkUpdate();
     return true;
@@ -305,19 +305,19 @@ void StaticModel::ApplyMaterialList(const String& fileName)
     String useFileName = fileName;
     if (useFileName.Trimmed().Empty() && model_)
         useFileName = ReplaceExtension(model_->GetName(), ".txt");
-    
+
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SharedPtr<File> file = cache->GetFile(useFileName, false);
     if (!file)
         return;
-    
+
     unsigned index = 0;
     while (!file->IsEof() && index < batches_.Size())
     {
         Material* material = cache->GetResource<Material>(file->ReadLine());
         if (material)
             SetMaterial(index, material);
-        
+
         ++index;
     }
 }
@@ -331,7 +331,7 @@ bool StaticModel::IsInside(const Vector3& point) const
 {
     if (!node_)
         return false;
-    
+
     Vector3 localPosition = node_->GetWorldTransform().Inverse() * point;
     return IsInsideLocal(localPosition);
 }
@@ -341,9 +341,9 @@ bool StaticModel::IsInsideLocal(const Vector3& point) const
     // Early-out if point is not inside bounding box
     if (boundingBox_.IsInside(point) == OUTSIDE)
         return false;
-    
+
     Ray localRay(point, Vector3(1.0f, -1.0f, 1.0f));
-    
+
     for (unsigned i = 0; i < batches_.Size(); ++i)
     {
         Geometry* geometry = batches_[i].geometry_;
@@ -353,7 +353,7 @@ bool StaticModel::IsInsideLocal(const Vector3& point) const
                 return true;
         }
     }
-    
+
     return false;
 }
 
@@ -371,7 +371,7 @@ void StaticModel::SetNumGeometries(unsigned num)
     ResetLodLevels();
 }
 
-void StaticModel::SetModelAttr(ResourceRef value)
+void StaticModel::SetModelAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SetModel(cache->GetResource<Model>(value.name_));
@@ -394,7 +394,7 @@ const ResourceRefList& StaticModel::GetMaterialsAttr() const
     materialsAttr_.names_.Resize(batches_.Size());
     for (unsigned i = 0; i < batches_.Size(); ++i)
         materialsAttr_.names_[i] = GetResourceName(batches_[i].material_);
-    
+
     return materialsAttr_;
 }
 
@@ -413,7 +413,7 @@ void StaticModel::ResetLodLevels()
         batches_[i].geometry_ = geometries_[i][0];
         geometryData_[i].lodLevel_ = 0;
     }
-    
+
     // Find out the real LOD levels on next geometry update
     lodDistance_ = M_INFINITY;
 }
@@ -426,15 +426,15 @@ void StaticModel::CalculateLodLevels()
         // If only one LOD geometry, no reason to go through the LOD calculation
         if (batchGeometries.Size() <= 1)
             continue;
-        
+
         unsigned j;
-        
+
         for (j = 1; j < batchGeometries.Size(); ++j)
         {
             if (batchGeometries[j] && lodDistance_ <= batchGeometries[j]->GetLodDistance())
                 break;
         }
-        
+
         unsigned newLodLevel = j - 1;
         if (geometryData_[i].lodLevel_ != newLodLevel)
         {

+ 9 - 9
Source/Engine/Graphics/StaticModel.h

@@ -42,7 +42,7 @@ struct StaticModelGeometryData
 class URHO3D_API StaticModel : public Drawable
 {
     OBJECT(StaticModel);
-    
+
 public:
     /// Construct.
     StaticModel(Context* context);
@@ -50,7 +50,7 @@ public:
     ~StaticModel();
     /// Register object factory. Drawable must be registered first.
     static void RegisterObject(Context* context);
-    
+
     /// Process octree raycast. May be called from a worker thread.
     virtual void ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQueryResult>& results);
     /// Calculate distance and prepare batches for rendering. May be called from worker thread(s), possibly re-entrantly.
@@ -61,7 +61,7 @@ public:
     virtual unsigned GetNumOccluderTriangles();
     /// Draw to occlusion buffer. Return true if did not run out of triangles.
     virtual bool DrawOcclusion(OcclusionBuffer* buffer);
-    
+
     /// Set model.
     void SetModel(Model* model);
     /// Set material on all geometries.
@@ -72,7 +72,7 @@ public:
     void SetOcclusionLodLevel(unsigned level);
     /// Apply default materials from a material list file. If filename is empty (default), the model's resource name with extension .txt will be used.
     void ApplyMaterialList(const String& fileName = String::EMPTY);
-    
+
     /// Return model.
     Model* GetModel() const { return model_; }
     /// Return number of geometries.
@@ -85,16 +85,16 @@ public:
     bool IsInside(const Vector3& point) const;
     /// Determines if the given local space point is within the model geometry.
     bool IsInsideLocal(const Vector3& point) const;
-    
+
     /// Set model attribute.
-    void SetModelAttr(ResourceRef value);
+    void SetModelAttr(const ResourceRef& value);
     /// Set materials attribute.
     void SetMaterialsAttr(const ResourceRefList& value);
     /// Return model attribute.
     ResourceRef GetModelAttr() const;
     /// Return materials attribute.
     const ResourceRefList& GetMaterialsAttr() const;
-    
+
 protected:
     /// Recalculate the world-space bounding box.
     virtual void OnWorldBoundingBoxUpdate();
@@ -106,7 +106,7 @@ protected:
     void ResetLodLevels();
     /// Choose LOD levels based on distance.
     void CalculateLodLevels();
-    
+
     /// Extra per-geometry data.
     PODVector<StaticModelGeometryData> geometryData_;
     /// All geometries.
@@ -117,7 +117,7 @@ protected:
     unsigned occlusionLodLevel_;
     /// Material list attribute.
     mutable ResourceRefList materialsAttr_;
-    
+
 private:
     /// Handle model reload finished.
     void HandleModelReloadFinished(StringHash eventType, VariantMap& eventData);

+ 2 - 2
Source/Engine/Graphics/StaticModelGroup.cpp

@@ -54,8 +54,8 @@ void StaticModelGroup::RegisterObject(Context* context)
 {
     context->RegisterFactory<StaticModelGroup>(GEOMETRY_CATEGORY);
 
-    COPY_BASE_ATTRIBUTES(StaticModelGroup, StaticModel);
-    REF_ACCESSOR_ATTRIBUTE(StaticModelGroup, VAR_VARIANTVECTOR, "Instance Nodes", GetNodeIDsAttr, SetNodeIDsAttr, VariantVector, Variant::emptyVariantVector, AM_DEFAULT | AM_NODEIDVECTOR);
+    COPY_BASE_ATTRIBUTES(StaticModel);
+    ACCESSOR_ATTRIBUTE("Instance Nodes", GetNodeIDsAttr, SetNodeIDsAttr, VariantVector, Variant::emptyVariantVector, AM_DEFAULT | AM_NODEIDVECTOR);
 }
 
 void StaticModelGroup::ApplyAttributes()

+ 48 - 48
Source/Engine/Graphics/Terrain.cpp

@@ -94,23 +94,23 @@ void Terrain::RegisterObject(Context* context)
 {
     context->RegisterFactory<Terrain>(GEOMETRY_CATEGORY);
 
-    ACCESSOR_ATTRIBUTE(Terrain, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Terrain, VAR_RESOURCEREF, "Height Map", GetHeightMapAttr, SetHeightMapAttr, ResourceRef, ResourceRef(Image::GetTypeStatic()), AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Terrain, VAR_RESOURCEREF, "Material", GetMaterialAttr, SetMaterialAttr, ResourceRef, ResourceRef(Material::GetTypeStatic()), AM_DEFAULT);
-    ATTRIBUTE(Terrain, VAR_VECTOR3, "Vertex Spacing", spacing_, DEFAULT_SPACING, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Terrain, VAR_INT, "Patch Size", GetPatchSize, SetPatchSizeAttr, int, DEFAULT_PATCH_SIZE, AM_DEFAULT);
-    ATTRIBUTE(Terrain, VAR_BOOL, "Smooth Height Map", smoothing_, false, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Terrain, VAR_BOOL, "Is Occluder", IsOccluder, SetOccluder, bool,  false, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Terrain, VAR_BOOL, "Can Be Occluded", IsOccludee, SetOccludee, bool, true, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Terrain, VAR_BOOL, "Cast Shadows", GetCastShadows, SetCastShadows, bool, false, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Terrain, VAR_FLOAT, "Draw Distance", GetDrawDistance, SetDrawDistance, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Terrain, VAR_FLOAT, "Shadow Distance", GetShadowDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Terrain, VAR_FLOAT, "LOD Bias", GetLodBias, SetLodBias, float, 1.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Terrain, VAR_INT, "Max Lights", GetMaxLights, SetMaxLights, unsigned, 0, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Terrain, VAR_INT, "View Mask", GetViewMask, SetViewMask, unsigned, DEFAULT_VIEWMASK, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Terrain, VAR_INT, "Light Mask", GetLightMask, SetLightMask, unsigned, DEFAULT_LIGHTMASK, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Terrain, VAR_INT, "Shadow Mask", GetShadowMask, SetShadowMask, unsigned, DEFAULT_SHADOWMASK, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Terrain, VAR_INT, "Zone Mask", GetZoneMask, SetZoneMask, unsigned, DEFAULT_ZONEMASK, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Height Map", GetHeightMapAttr, SetHeightMapAttr, ResourceRef, ResourceRef(Image::GetTypeStatic()), AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Material", GetMaterialAttr, SetMaterialAttr, ResourceRef, ResourceRef(Material::GetTypeStatic()), AM_DEFAULT);
+    ATTRIBUTE("Vertex Spacing", Vector3, spacing_, DEFAULT_SPACING, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Patch Size", GetPatchSize, SetPatchSizeAttr, int, DEFAULT_PATCH_SIZE, AM_DEFAULT);
+    ATTRIBUTE("Smooth Height Map", bool, smoothing_, false, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Is Occluder", IsOccluder, SetOccluder, bool,  false, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Can Be Occluded", IsOccludee, SetOccludee, bool, true, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Cast Shadows", GetCastShadows, SetCastShadows, bool, false, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Draw Distance", GetDrawDistance, SetDrawDistance, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Shadow Distance", GetShadowDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("LOD Bias", GetLodBias, SetLodBias, float, 1.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Max Lights", GetMaxLights, SetMaxLights, unsigned, 0, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("View Mask", GetViewMask, SetViewMask, unsigned, DEFAULT_VIEWMASK, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Light Mask", GetLightMask, SetLightMask, unsigned, DEFAULT_LIGHTMASK, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Shadow Mask", GetShadowMask, SetShadowMask, unsigned, DEFAULT_SHADOWMASK, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Zone Mask", GetZoneMask, SetZoneMask, unsigned, DEFAULT_ZONEMASK, AM_DEFAULT);
 }
 
 void Terrain::OnSetAttribute(const AttributeInfo& attr, const Variant& src)
@@ -427,13 +427,13 @@ IntVector2 Terrain::WorldToHeightMap(const Vector3& worldPosition) const
 {
     if (!node_)
         return IntVector2::ZERO;
-    
+
     Vector3 position = node_->GetWorldTransform().Inverse() * worldPosition;
     int xPos = (int)((position.x_ - patchWorldOrigin_.x_) / spacing_.x_);
     int zPos = (int)((position.z_ - patchWorldOrigin_.y_) / spacing_.z_);
     Clamp(xPos, 0, numVertices_.x_);
     Clamp(zPos, 0, numVertices_.y_);
-    
+
     return IntVector2(xPos, numVertices_.y_ - zPos);
 }
 
@@ -552,13 +552,13 @@ void Terrain::UpdatePatchLod(TerrainPatch* patch)
         geometry->SetDrawRange(TRIANGLE_LIST, drawRanges_[drawRangeIndex].first_, drawRanges_[drawRangeIndex].second_, false);
 }
 
-void Terrain::SetMaterialAttr(ResourceRef value)
+void Terrain::SetMaterialAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SetMaterial(cache->GetResource<Material>(value.name_));
 }
 
-void Terrain::SetHeightMapAttr(ResourceRef value)
+void Terrain::SetHeightMapAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     Image* image = cache->GetResource<Image>(value.name_);
@@ -590,7 +590,7 @@ ResourceRef Terrain::GetHeightMapAttr() const
 void Terrain::CreateGeometry()
 {
     recreateTerrain_ = false;
-    
+
     if (!node_)
         return;
 
@@ -610,7 +610,7 @@ void Terrain::CreateGeometry()
     // Determine total terrain size
     patchWorldSize_ = Vector2(spacing_.x_ * (float)patchSize_, spacing_.z_ * (float)patchSize_);
     bool updateAll = false;
-    
+
     if (heightMap_)
     {
         numPatches_ = IntVector2((heightMap_->GetWidth() - 1) / patchSize_, (heightMap_->GetHeight() - 1) / patchSize_);
@@ -620,11 +620,11 @@ void Terrain::CreateGeometry()
         if (numVertices_ != lastNumVertices_ || lastSpacing_ != spacing_ || patchSize_ != lastPatchSize_ )
             updateAll = true;
         unsigned newDataSize = numVertices_.x_ * numVertices_.y_;
-        
+
         // Create new height data if terrain size changed
         if (!heightData_ || updateAll)
             heightData_ = new float[newDataSize];
-        
+
         // Ensure that the source (unsmoothed) data exists if smoothing is active
         if (smoothing_ && (!sourceHeightData_ || updateAll))
         {
@@ -646,12 +646,12 @@ void Terrain::CreateGeometry()
     lastNumVertices_ = numVertices_;
     lastPatchSize_ = patchSize_;
     lastSpacing_ = spacing_;
-    
+
     // Remove old patch nodes which are not needed
     if (updateAll)
     {
         PROFILE(RemoveOldPatches);
-        
+
         PODVector<Node*> oldPatchNodes;
         node_->GetChildrenWithComponent<TerrainPatch>(oldPatchNodes);
         for (PODVector<Node*>::Iterator i = oldPatchNodes.Begin(); i != oldPatchNodes.End(); ++i)
@@ -675,7 +675,7 @@ void Terrain::CreateGeometry()
     PODVector<bool> dirtyPatches(numPatches_.x_ * numPatches_.y_);
     for (unsigned i = 0; i < dirtyPatches.Size(); ++i)
         dirtyPatches[i] = updateAll;
-    
+
     patches_.Clear();
 
     if (heightMap_)
@@ -689,13 +689,13 @@ void Terrain::CreateGeometry()
         if (imgComps == 1)
         {
             PROFILE(CopyHeightData);
-            
+
             for (int z = 0; z < numVertices_.y_; ++z)
             {
                 for (int x = 0; x < numVertices_.x_; ++x)
                 {
                     float newHeight = (float)src[imgRow * (numVertices_.y_ - 1 - z) + x] * spacing_.y_;
-                    
+
                     if (updateAll)
                         *dest = newHeight;
                     else
@@ -710,11 +710,11 @@ void Terrain::CreateGeometry()
                                     for (int x1 = x - 1; x1 <= z + 1; ++x1)
                                         MarkPatchesDirty(dirtyPatches, x1, z1);
                             }
-                            
+
                             *dest = newHeight;
                         }
                     }
-                    
+
                     ++dest;
                 }
             }
@@ -722,7 +722,7 @@ void Terrain::CreateGeometry()
         else
         {
             PROFILE(CopyHeightData);
-            
+
             // If more than 1 component, use the green channel for more accuracy
             for (int z = 0; z < numVertices_.y_; ++z)
             {
@@ -730,7 +730,7 @@ void Terrain::CreateGeometry()
                 {
                     float newHeight = ((float)src[imgRow * (numVertices_.y_ - 1 - z) + imgComps * x] + (float)src[imgRow *
                         (numVertices_.y_ - 1 - z) + imgComps * x + 1] / 256.0f) * spacing_.y_;
-                        
+
                     if (updateAll)
                         *dest = newHeight;
                     else
@@ -745,11 +745,11 @@ void Terrain::CreateGeometry()
                                     for (int x1 = x - 1; x1 <= z + 1; ++x1)
                                         MarkPatchesDirty(dirtyPatches, x1, z1);
                             }
-                            
+
                             *dest = newHeight;
                         }
                     }
-                    
+
                     ++dest;
                 }
             }
@@ -761,7 +761,7 @@ void Terrain::CreateGeometry()
 
         {
             PROFILE(CreatePatches);
-            
+
             // Create patches and set node transforms
             for (int z = 0; z < numPatches_.y_; ++z)
             {
@@ -769,7 +769,7 @@ void Terrain::CreateGeometry()
                 {
                     String nodeName = "Patch_" + String(x) + "_" + String(z);
                     Node* patchNode = node_->GetChild(nodeName);
-                    
+
                     if (!patchNode)
                     {
                         // Create the patch scene node as local and temporary so that it is not unnecessarily serialized to either
@@ -777,7 +777,7 @@ void Terrain::CreateGeometry()
                         patchNode = node_->CreateChild(nodeName, LOCAL);
                         patchNode->SetTemporary(true);
                     }
-                    
+
                     patchNode->SetPosition(Vector3(patchWorldOrigin_.x_ + (float)x * patchWorldSize_.x_, 0.0f, patchWorldOrigin_.y_ +
                         (float)z * patchWorldSize_.y_));
 
@@ -808,7 +808,7 @@ void Terrain::CreateGeometry()
                 }
             }
         }
-        
+
         // Create the shared index data
         if (updateAll)
             CreateIndexData();
@@ -817,7 +817,7 @@ void Terrain::CreateGeometry()
         if (smoothing_)
         {
             PROFILE(UpdateSmoothing);
-            
+
             for (unsigned i = 0; i < patches_.Size(); ++i)
             {
                 if (dirtyPatches[i])
@@ -828,7 +828,7 @@ void Terrain::CreateGeometry()
                     int endX = startX + patchSize_;
                     int startZ = coords.y_ * patchSize_;
                     int endZ = startZ + patchSize_;
-                    
+
                     for (int z = startZ; z <= endZ; ++z)
                     {
                         for (int x = startX; x <= endX; ++x)
@@ -838,24 +838,24 @@ void Terrain::CreateGeometry()
                                 GetSourceHeight(x - 1, z) * 2.0f + GetSourceHeight(x, z) * 4.0f + GetSourceHeight(x + 1, z) * 2.0f +
                                 GetSourceHeight(x - 1, z + 1) + GetSourceHeight(x, z + 1) * 2.0f + GetSourceHeight(x + 1, z + 1)
                             ) / 16.0f;
-                            
+
                             heightData_[z * numVertices_.x_ + x] = smoothedHeight;
                         }
                     }
                 }
             }
         }
-        
+
         for (unsigned i = 0; i < patches_.Size(); ++i)
         {
             TerrainPatch* patch = patches_[i];
-            
+
             if (dirtyPatches[i])
             {
                 CreatePatchGeometry(patch);
                 CalculateLodErrors(patch);
             }
-            
+
             SetNeighbors(patch);
         }
     }
@@ -881,7 +881,7 @@ void Terrain::CreateIndexData()
 
     /* Build index data for each LOD level. Each LOD level except the lowest can stitch to the next lower LOD from the edges:
        north, south, west, east, or any combination of them, requiring 16 different versions of each LOD level's index data
-    
+
        Normal edge:     Stitched edge:
        +----+----+      +---------+
        |\   |\   |      |\       /|
@@ -1181,7 +1181,7 @@ void Terrain::MarkPatchesDirty(PODVector<bool>& dirtyPatches, int x, int z)
 {
     x = Clamp(x, 0, numVertices_.x_);
     z = Clamp(z, 0, numVertices_.y_);
-    
+
     // A point on the heightmap can potentially belong to multiple patches; dirty all that are applicable
     int pZ = z / patchSize_;
     int vZ = z % patchSize_;

+ 3 - 3
Source/Engine/Graphics/Terrain.h

@@ -144,9 +144,9 @@ public:
     /// Update patch based on LOD and neighbor LOD.
     void UpdatePatchLod(TerrainPatch* patch);
     /// Set heightmap attribute.
-    void SetHeightMapAttr(ResourceRef value);
+    void SetHeightMapAttr(const ResourceRef& value);
     /// Set material attribute.
-    void SetMaterialAttr(ResourceRef value);
+    void SetMaterialAttr(const ResourceRef& value);
     /// Set patch size attribute.
     void SetPatchSizeAttr(int value);
     /// Return heightmap attribute.
@@ -177,7 +177,7 @@ private:
     void HandleHeightMapReloadFinished(StringHash eventType, VariantMap& eventData);
     /// Mark patch(es) dirty based on location. Used when checking the heightmap image for changes.
     void MarkPatchesDirty(PODVector<bool>& dirtyPatches, int x, int z);
-    
+
     /// Shared index buffer.
     SharedPtr<IndexBuffer> indexBuffer_;
     /// Heightmap image.

+ 20 - 20
Source/Engine/Graphics/Zone.cpp

@@ -71,23 +71,23 @@ void Zone::RegisterObject(Context* context)
 {
     context->RegisterFactory<Zone>(SCENE_CATEGORY);
 
-    ACCESSOR_ATTRIBUTE(Zone, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
-    ATTRIBUTE(Zone, VAR_VECTOR3, "Bounding Box Min", boundingBox_.min_, DEFAULT_BOUNDING_BOX_MIN, AM_DEFAULT);
-    ATTRIBUTE(Zone, VAR_VECTOR3, "Bounding Box Max", boundingBox_.max_, DEFAULT_BOUNDING_BOX_MAX, AM_DEFAULT);
-    ATTRIBUTE(Zone, VAR_COLOR, "Ambient Color", ambientColor_, DEFAULT_AMBIENT_COLOR, AM_DEFAULT);
-    ATTRIBUTE(Zone, VAR_COLOR, "Fog Color", fogColor_, DEFAULT_FOG_COLOR, AM_DEFAULT);
-    ATTRIBUTE(Zone, VAR_FLOAT, "Fog Start", fogStart_, DEFAULT_FOG_START, AM_DEFAULT);
-    ATTRIBUTE(Zone, VAR_FLOAT, "Fog End", fogEnd_, DEFAULT_FOG_END, AM_DEFAULT);
-    ATTRIBUTE(Zone, VAR_FLOAT, "Fog Height", fogHeight_, DEFAULT_FOG_HEIGHT, AM_DEFAULT);
-    ATTRIBUTE(Zone, VAR_FLOAT, "Fog Height Scale", fogHeightScale_, DEFAULT_FOG_HEIGHT_SCALE, AM_DEFAULT);
-    ATTRIBUTE(Zone, VAR_BOOL, "Height Fog Mode", heightFog_, false, AM_DEFAULT);
-    ATTRIBUTE(Zone, VAR_BOOL, "Override Mode", override_, false, AM_DEFAULT);
-    ATTRIBUTE(Zone, VAR_BOOL, "Ambient Gradient", ambientGradient_, false, AM_DEFAULT);
-    ATTRIBUTE(Zone, VAR_INT, "Priority", priority_, 0, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Zone, VAR_RESOURCEREF, "Zone Texture", GetZoneTextureAttr, SetZoneTextureAttr, ResourceRef, ResourceRef(TextureCube::GetTypeStatic()), AM_DEFAULT);
-    ATTRIBUTE(Zone, VAR_INT, "Light Mask", lightMask_, DEFAULT_LIGHTMASK, AM_DEFAULT);
-    ATTRIBUTE(Zone, VAR_INT, "Shadow Mask", shadowMask_, DEFAULT_SHADOWMASK, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Zone, VAR_INT, "Zone Mask", GetZoneMask, SetZoneMask, unsigned, DEFAULT_ZONEMASK, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
+    ATTRIBUTE("Bounding Box Min", Vector3, boundingBox_.min_, DEFAULT_BOUNDING_BOX_MIN, AM_DEFAULT);
+    ATTRIBUTE("Bounding Box Max", Vector3, boundingBox_.max_, DEFAULT_BOUNDING_BOX_MAX, AM_DEFAULT);
+    ATTRIBUTE("Ambient Color", Color, ambientColor_, DEFAULT_AMBIENT_COLOR, AM_DEFAULT);
+    ATTRIBUTE("Fog Color", Color, fogColor_, DEFAULT_FOG_COLOR, AM_DEFAULT);
+    ATTRIBUTE("Fog Start", float, fogStart_, DEFAULT_FOG_START, AM_DEFAULT);
+    ATTRIBUTE("Fog End", float, fogEnd_, DEFAULT_FOG_END, AM_DEFAULT);
+    ATTRIBUTE("Fog Height", float, fogHeight_, DEFAULT_FOG_HEIGHT, AM_DEFAULT);
+    ATTRIBUTE("Fog Height Scale", float, fogHeightScale_, DEFAULT_FOG_HEIGHT_SCALE, AM_DEFAULT);
+    ATTRIBUTE("Height Fog Mode", bool, heightFog_, false, AM_DEFAULT);
+    ATTRIBUTE("Override Mode", bool, override_, false, AM_DEFAULT);
+    ATTRIBUTE("Ambient Gradient", bool, ambientGradient_, false, AM_DEFAULT);
+    ATTRIBUTE("Priority", int, priority_, 0, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Zone Texture", GetZoneTextureAttr, SetZoneTextureAttr, ResourceRef, ResourceRef(TextureCube::GetTypeStatic()), AM_DEFAULT);
+    ATTRIBUTE("Light Mask", int, lightMask_, DEFAULT_LIGHTMASK, AM_DEFAULT);
+    ATTRIBUTE("Shadow Mask", int, shadowMask_, DEFAULT_SHADOWMASK, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Zone Mask", GetZoneMask, SetZoneMask, unsigned, DEFAULT_ZONEMASK, AM_DEFAULT);
 }
 
 void Zone::OnSetAttribute(const AttributeInfo& attr, const Variant& src)
@@ -225,7 +225,7 @@ bool Zone::IsInside(const Vector3& point) const
     return boundingBox_.IsInside(localPoint) != OUTSIDE;
 }
 
-void Zone::SetZoneTextureAttr(ResourceRef value)
+void Zone::SetZoneTextureAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     zoneTexture_ = static_cast<Texture*>(cache->GetResource(value.type_, value.name_));
@@ -247,10 +247,10 @@ void Zone::OnMarkedDirty(Node* node)
     }
 
     Drawable::OnMarkedDirty(node);
-    
+
     // Clear zone reference from all drawables inside the bounding box, and mark gradient dirty in neighbor zones
     ClearDrawablesZone();
-    
+
     inverseWorldDirty_ = true;
 }
 

+ 8 - 8
Source/Engine/Graphics/Zone.h

@@ -33,7 +33,7 @@ namespace Urho3D
 class URHO3D_API Zone : public Drawable
 {
     OBJECT(Zone);
-    
+
 public:
     /// Construct.
     Zone(Context* context);
@@ -41,12 +41,12 @@ public:
     virtual ~Zone();
     /// Register object factory. Drawable must be registered first.
     static void RegisterObject(Context* context);
-    
+
     /// Handle attribute write access.
     virtual void OnSetAttribute(const AttributeInfo& attr, const Variant& src);
     /// Visualize the component as debug geometry.
     virtual void DrawDebugGeometry(DebugRenderer* debug, bool depthTest);
-    
+
     /// Set local-space bounding box. Will be used as an oriented bounding box to test whether objects or the camera are inside.
     void SetBoundingBox(const BoundingBox& box);
     /// Set ambient color
@@ -71,7 +71,7 @@ public:
     void SetAmbientGradient(bool enable);
     /// Set zone texture. This will be bound to the zone texture unit when rendering objects inside the zone. Note that the default shaders do not use it.
     void SetZoneTexture(Texture* texture);
-    
+
     /// Return inverse world transform.
     const Matrix3x4& GetInverseWorldTransform() const;
     /// Return zone's own ambient color, disregarding gradient mode.
@@ -100,14 +100,14 @@ public:
     bool GetAmbientGradient() const { return ambientGradient_; }
     /// Return zone texture.
     Texture* GetZoneTexture() const { return zoneTexture_; }
-    
+
     /// Check whether a point is inside.
     bool IsInside(const Vector3& point) const;
     /// Set zone texture attribute.
-    void SetZoneTextureAttr(ResourceRef value);
+    void SetZoneTextureAttr(const ResourceRef& value);
     /// Return zone texture attribute.
     ResourceRef GetZoneTextureAttr() const;
-    
+
 protected:
     /// Handle node transform being dirtied.
     virtual void OnMarkedDirty(Node* node);
@@ -119,7 +119,7 @@ protected:
     void UpdateAmbientGradient();
     /// Clear zone reference from drawables inside the bounding box.
     void ClearDrawablesZone();
-    
+
     /// Cached inverse world transform matrix.
     mutable Matrix3x4 inverseWorld_;
     /// Inverse transform dirty flag.

+ 10 - 10
Source/Engine/LuaScript/LuaScriptInstance.cpp

@@ -86,11 +86,11 @@ void LuaScriptInstance::RegisterObject(Context* context)
 {
     context->RegisterFactory<LuaScriptInstance>(LOGIC_CATEGORY);
 
-    ACCESSOR_ATTRIBUTE(LuaScriptInstance, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(LuaScriptInstance, VAR_RESOURCEREF, "Script File", GetScriptFileAttr, SetScriptFileAttr, ResourceRef, ResourceRef(LuaFile::GetTypeStatic()), AM_DEFAULT);
-    REF_ACCESSOR_ATTRIBUTE(LuaScriptInstance, VAR_STRING, "Script Object Type", GetScriptObjectType, SetScriptObjectType, String, String::EMPTY, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(LuaScriptInstance, VAR_BUFFER, "Script Data", GetScriptDataAttr, SetScriptDataAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_FILE | AM_NOEDIT);
-    ACCESSOR_ATTRIBUTE(LuaScriptInstance, VAR_BUFFER, "Script Network Data", GetScriptNetworkDataAttr, SetScriptNetworkDataAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_NET | AM_NOEDIT);
+    ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Script File", GetScriptFileAttr, SetScriptFileAttr, ResourceRef, ResourceRef(LuaFile::GetTypeStatic()), AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Script Object Type", GetScriptObjectType, SetScriptObjectType, String, String::EMPTY, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Script Data", GetScriptDataAttr, SetScriptDataAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_FILE | AM_NOEDIT);
+    MIXED_ACCESSOR_ATTRIBUTE("Script Network Data", GetScriptNetworkDataAttr, SetScriptNetworkDataAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_NET | AM_NOEDIT);
 }
 
 void LuaScriptInstance::OnSetAttribute(const AttributeInfo& attr, const Variant& src)
@@ -157,7 +157,7 @@ void LuaScriptInstance::OnSetAttribute(const AttributeInfo& attr, const Variant&
                 Vector4* value = new Vector4(src.GetVector4());
                 tolua_pushusertype(luaState_, value, "Vector4");
                 tolua_register_gc(luaState_, lua_gettop(luaState_));
-            }            
+            }
             break;
         case VAR_QUATERNION:
             {
@@ -165,7 +165,7 @@ void LuaScriptInstance::OnSetAttribute(const AttributeInfo& attr, const Variant&
                 tolua_pushusertype(luaState_, value, "Quaternion");
                 tolua_register_gc(luaState_, lua_gettop(luaState_));
             }
-            
+
             break;
         case VAR_COLOR:
             {
@@ -344,7 +344,7 @@ void LuaScriptInstance::SetScriptObjectType(const String& scriptObjectType)
     FindScriptObjectMethodRefs();
 }
 
-void LuaScriptInstance::SetScriptDataAttr(PODVector<unsigned char> data)
+void LuaScriptInstance::SetScriptDataAttr(const PODVector<unsigned char>& data)
 {
     if (scriptObjectRef_ == LUA_REFNIL)
         return;
@@ -358,7 +358,7 @@ void LuaScriptInstance::SetScriptDataAttr(PODVector<unsigned char> data)
     }
 }
 
-void LuaScriptInstance::SetScriptNetworkDataAttr(PODVector<unsigned char> data)
+void LuaScriptInstance::SetScriptNetworkDataAttr(const PODVector<unsigned char>& data)
 {
     if (scriptObjectRef_ == LUA_REFNIL)
         return;
@@ -767,7 +767,7 @@ WeakPtr<LuaFunction> LuaScriptInstance::GetScriptObjectFunction(const String& fu
     return luaScript_->GetFunction(scriptObjectType_ + "." + functionName, true);
 }
 
-void LuaScriptInstance::SetScriptFileAttr(ResourceRef value)
+void LuaScriptInstance::SetScriptFileAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SetScriptFile(cache->GetResource<LuaFile>(value.name_));

+ 3 - 3
Source/Engine/LuaScript/LuaScriptInstance.h

@@ -84,9 +84,9 @@ public:
     /// Set script object type.
     void SetScriptObjectType(const String& scriptObjectType);
     /// Set script file serialization attribute by calling a script function.
-    void SetScriptDataAttr(PODVector<unsigned char> data);
+    void SetScriptDataAttr(const PODVector<unsigned char>& data);
     /// Set script network serialization attribute by calling a script function.
-    void SetScriptNetworkDataAttr(PODVector<unsigned char> data);
+    void SetScriptNetworkDataAttr(const PODVector<unsigned char>& data);
     /// Script subscribe to an event that can by send by any sender.
     void ScriptSubscribeToEvent(const String& eventName, int functionIndex);
     /// Script subscribe to an event that can by send by any sender.
@@ -118,7 +118,7 @@ public:
     WeakPtr<LuaFunction> GetScriptObjectFunction(const String& functionName) const;
 
 	/// Set script file attribute.
-	void SetScriptFileAttr(ResourceRef value);
+	void SetScriptFileAttr(const ResourceRef& value);
 	/// Return script file attribute.
 	ResourceRef GetScriptFileAttr() const;
 

+ 1 - 1
Source/Engine/LuaScript/pkgs/Physics/PhysicsWorld.pkg

@@ -16,7 +16,7 @@ class PhysicsWorld : public Component
     void Update(float timeStep);
     void UpdateCollisions();
     void SetFps(int fps);
-    void SetGravity(Vector3 gravity);
+    void SetGravity(const Vector3& gravity);
     void SetMaxSubSteps(int num);
     void SetNumIterations(int num);
     void SetInterpolation(bool enable);

+ 7 - 7
Source/Engine/LuaScript/pkgs/Physics/RigidBody.pkg

@@ -10,19 +10,19 @@ enum CollisionEventMode
 class RigidBody : public Component
 {
     void SetMass(float mass);
-    void SetPosition(Vector3 position);
-    void SetRotation(Quaternion rotation);
+    void SetPosition(const Vector3& position);
+    void SetRotation(const Quaternion& rotation);
     void SetTransform(const Vector3& position, const Quaternion& rotation);
-    void SetLinearVelocity(Vector3 velocity);
-    void SetLinearFactor(Vector3 factor);
+    void SetLinearVelocity(const Vector3& velocity);
+    void SetLinearFactor(const Vector3& factor);
     void SetLinearRestThreshold(float threshold);
     void SetLinearDamping(float damping);
-    void SetAngularVelocity(Vector3 angularVelocity);
-    void SetAngularFactor(Vector3 factor);
+    void SetAngularVelocity(const Vector3& angularVelocity);
+    void SetAngularFactor(const Vector3& factor);
     void SetAngularRestThreshold(float threshold);
     void SetAngularDamping(float factor);
     void SetFriction(float friction);
-    void SetAnisotropicFriction(Vector3 friction);
+    void SetAnisotropicFriction(const Vector3& friction);
     void SetRollingFriction(float friction);
     void SetRestitution(float restitution);
     void SetContactProcessingThreshold(float threshold);

+ 1 - 1
Source/Engine/LuaScript/pkgs/Scene/Scene.pkg

@@ -70,7 +70,7 @@ class Scene : public Node
     void NodeRemoved(Node* node);
     void ComponentAdded(Component* component);
     void ComponentRemoved(Component* component);
-    void SetVarNamesAttr(String value);
+    void SetVarNamesAttr(const String value);
     String GetVarNamesAttr() const;
     void PrepareNetworkUpdate();
     void CleanupConnection(Connection* connection);

+ 2 - 2
Source/Engine/LuaScript/pkgs/Urho2D/RigidBody2D.pkg

@@ -12,7 +12,7 @@ class RigidBody2D : Component
     void SetBodyType(BodyType2D bodyType);
     void SetMass(float mass);
     void SetInertia(float inertia);
-    void SetMassCenter(Vector2 center);
+    void SetMassCenter(const Vector2& center);
     void SetUseFixtureMass(bool useFixtureMass);
     void SetLinearDamping(float linearDamping);
     void SetAngularDamping(float angularDamping);
@@ -21,7 +21,7 @@ class RigidBody2D : Component
     void SetBullet(bool bullet);
     void SetGravityScale(float gravityScale);
     void SetAwake(bool awake);
-    void SetLinearVelocity(Vector2 linearVelocity);
+    void SetLinearVelocity(const Vector2& linearVelocity);
     void SetAngularVelocity(float angularVelocity);
     void ApplyForce(const Vector2& force, const Vector2& point,  bool wake);
     void ApplyForceToCenter(const Vector2& force, bool wake);

+ 2 - 2
Source/Engine/Navigation/Navigable.cpp

@@ -45,8 +45,8 @@ void Navigable::RegisterObject(Context* context)
 {
     context->RegisterFactory<Navigable>(NAVIGATION_CATEGORY);
 
-    ACCESSOR_ATTRIBUTE(Navigable, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
-    ATTRIBUTE(Navigable, VAR_BOOL, "Recursive", recursive_, true, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
+    ATTRIBUTE("Recursive", bool, recursive_, true, AM_DEFAULT);
 }
 
 void Navigable::SetRecursive(bool enable)

File diff suppressed because it is too large
+ 174 - 174
Source/Engine/Navigation/NavigationMesh.cpp


+ 8 - 8
Source/Engine/Navigation/NavigationMesh.h

@@ -57,7 +57,7 @@ struct NavigationGeometryInfo
 class URHO3D_API NavigationMesh : public Component
 {
     OBJECT(NavigationMesh);
-    
+
 public:
     /// Construct.
     NavigationMesh(Context* context);
@@ -65,10 +65,10 @@ public:
     virtual ~NavigationMesh();
     /// Register object factory.
     static void RegisterObject(Context* context);
-    
+
     /// Visualize the component as debug geometry.
     virtual void DrawDebugGeometry(DebugRenderer* debug, bool depthTest);
-    
+
     /// Set tile size.
     void SetTileSize(int size);
     /// Set cell size.
@@ -117,7 +117,7 @@ public:
     Vector3 Raycast(const Vector3& start, const Vector3& end, const Vector3& extents = Vector3::ONE);
     /// Add debug geometry to the debug renderer.
     void DrawDebugGeometry(bool depthTest);
-    
+
     /// Return tile size.
     int GetTileSize() const { return tileSize_; }
     /// Return cell size.
@@ -154,12 +154,12 @@ public:
     BoundingBox GetWorldBoundingBox() const;
     /// Return number of tiles.
     IntVector2 GetNumTiles() const { return IntVector2(numTilesX_, numTilesZ_); }
-    
+
     /// Set navigation data attribute.
-    void SetNavigationDataAttr(PODVector<unsigned char> value);
+    void SetNavigationDataAttr(const PODVector<unsigned char>& value);
     /// Return navigation data attribute.
     PODVector<unsigned char> GetNavigationDataAttr() const;
-    
+
 private:
     /// Collect geometry from under Navigable components.
     void CollectGeometries(Vector<NavigationGeometryInfo>& geometryList);
@@ -175,7 +175,7 @@ private:
     bool InitializeQuery();
     /// Release the navigation mesh and the query.
     void ReleaseNavigationMesh();
-    
+
     /// Detour navigation mesh.
     dtNavMesh* navMesh_;
     /// Detour navigation mesh query.

+ 4 - 4
Source/Engine/Navigation/OffMeshConnection.cpp

@@ -52,10 +52,10 @@ void OffMeshConnection::RegisterObject(Context* context)
 {
     context->RegisterFactory<OffMeshConnection>(NAVIGATION_CATEGORY);
     
-    ACCESSOR_ATTRIBUTE(OffMeshConnection, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
-    ATTRIBUTE(OffMeshConnection, VAR_INT, "Endpoint NodeID", endPointID_, 0, AM_DEFAULT | AM_NODEID);
-    ATTRIBUTE(OffMeshConnection, VAR_FLOAT, "Radius", radius_, DEFAULT_RADIUS, AM_DEFAULT);
-    ATTRIBUTE(OffMeshConnection, VAR_BOOL, "Bidirectional", bidirectional_, true, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
+    ATTRIBUTE("Endpoint NodeID", int, endPointID_, 0, AM_DEFAULT | AM_NODEID);
+    ATTRIBUTE("Radius", float, radius_, DEFAULT_RADIUS, AM_DEFAULT);
+    ATTRIBUTE("Bidirectional", bool, bidirectional_, true, AM_DEFAULT);
 }
 
 void OffMeshConnection::OnSetAttribute(const AttributeInfo& attr, const Variant& src)

+ 4 - 4
Source/Engine/Network/NetworkPriority.cpp

@@ -53,10 +53,10 @@ void NetworkPriority::RegisterObject(Context* context)
 {
     context->RegisterFactory<NetworkPriority>(NETWORK_CATEGORY);
     
-    ATTRIBUTE(NetworkPriority, VAR_FLOAT, "Base Priority", basePriority_, DEFAULT_BASE_PRIORITY, AM_DEFAULT);
-    ATTRIBUTE(NetworkPriority, VAR_FLOAT, "Distance Factor", distanceFactor_, DEFAULT_DISTANCE_FACTOR, AM_DEFAULT);
-    ATTRIBUTE(NetworkPriority, VAR_FLOAT, "Minimum Priority", minPriority_, DEFAULT_MIN_PRIORITY, AM_DEFAULT);
-    ATTRIBUTE(NetworkPriority, VAR_BOOL, "Always Update Owner", alwaysUpdateOwner_, true, AM_DEFAULT);
+    ATTRIBUTE("Base Priority", float, basePriority_, DEFAULT_BASE_PRIORITY, AM_DEFAULT);
+    ATTRIBUTE("Distance Factor", float, distanceFactor_, DEFAULT_DISTANCE_FACTOR, AM_DEFAULT);
+    ATTRIBUTE("Minimum Priority", float, minPriority_, DEFAULT_MIN_PRIORITY, AM_DEFAULT);
+    ATTRIBUTE("Always Update Owner", bool, alwaysUpdateOwner_, true, AM_DEFAULT);
 }
 
 void NetworkPriority::SetBasePriority(float priority)

+ 16 - 16
Source/Engine/Physics/CollisionShape.cpp

@@ -132,7 +132,7 @@ public:
     {
         const Vector<PODVector<CustomGeometryVertex> >& srcVertices = custom->GetVertices();
         unsigned totalVertexCount = 0;
-        
+
         for (unsigned i = 0; i < srcVertices.Size(); ++i)
             totalVertexCount += srcVertices[i].Size();
 
@@ -143,11 +143,11 @@ public:
             SharedArrayPtr<unsigned char> indexData(new unsigned char[totalVertexCount * sizeof(unsigned)]);
             dataArrays_.Push(vertexData);
             dataArrays_.Push(indexData);
-            
+
             Vector3* destVertex = reinterpret_cast<Vector3*>(&vertexData[0]);
             unsigned* destIndex = reinterpret_cast<unsigned*>(&indexData[0]);
             unsigned k = 0;
-            
+
             for (unsigned i = 0; i < srcVertices.Size(); ++i)
             {
                 for (unsigned j = 0; j < srcVertices[i].Size(); ++j)
@@ -156,7 +156,7 @@ public:
                     *destIndex++ = k++;
                 }
             }
-            
+
             btIndexedMesh meshIndex;
             meshIndex.m_numTriangles = totalVertexCount / 3;
             meshIndex.m_triangleIndexBase = indexData;
@@ -169,7 +169,7 @@ public:
             m_indexedMeshes.push_back(meshIndex);
         }
     }
-    
+
 private:
     /// Shared vertex/index data used in the collision
     Vector<SharedArrayPtr<unsigned char> > dataArrays_;
@@ -262,7 +262,7 @@ ConvexData::ConvexData(CustomGeometry* custom)
         for (unsigned j = 0; j < srcVertices[i].Size(); ++j)
             vertices.Push(srcVertices[i][j].position_);
     }
-    
+
     BuildHull(vertices);
 }
 
@@ -383,15 +383,15 @@ void CollisionShape::RegisterObject(Context* context)
 {
     context->RegisterFactory<CollisionShape>(PHYSICS_CATEGORY);
 
-    ACCESSOR_ATTRIBUTE(CollisionShape, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
-    ENUM_ATTRIBUTE(CollisionShape, "Shape Type", shapeType_, typeNames, SHAPE_BOX, AM_DEFAULT);
-    ATTRIBUTE(CollisionShape, VAR_VECTOR3, "Size", size_, Vector3::ONE, AM_DEFAULT);
-    REF_ACCESSOR_ATTRIBUTE(CollisionShape, VAR_VECTOR3, "Offset Position", GetPosition, SetPosition, Vector3, Vector3::ZERO, AM_DEFAULT);
-    REF_ACCESSOR_ATTRIBUTE(CollisionShape, VAR_QUATERNION, "Offset Rotation", GetRotation, SetRotation, Quaternion, Quaternion::IDENTITY, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(CollisionShape, VAR_RESOURCEREF, "Model", GetModelAttr, SetModelAttr, ResourceRef, ResourceRef(Model::GetTypeStatic()), AM_DEFAULT);
-    ATTRIBUTE(CollisionShape, VAR_INT, "LOD Level", lodLevel_, 0, AM_DEFAULT);
-    ATTRIBUTE(CollisionShape, VAR_FLOAT, "Collision Margin", margin_, DEFAULT_COLLISION_MARGIN, AM_DEFAULT);
-    ATTRIBUTE(CollisionShape, VAR_INT, "CustomGeometry NodeID", customGeometryID_, 0, AM_DEFAULT | AM_NODEID);
+    ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
+    ENUM_ATTRIBUTE("Shape Type", shapeType_, typeNames, SHAPE_BOX, AM_DEFAULT);
+    ATTRIBUTE("Size", Vector3, size_, Vector3::ONE, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Offset Position", GetPosition, SetPosition, Vector3, Vector3::ZERO, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Offset Rotation", GetRotation, SetRotation, Quaternion, Quaternion::IDENTITY, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Model", GetModelAttr, SetModelAttr, ResourceRef, ResourceRef(Model::GetTypeStatic()), AM_DEFAULT);
+    ATTRIBUTE("LOD Level", int, lodLevel_, 0, AM_DEFAULT);
+    ATTRIBUTE("Collision Margin", float, margin_, DEFAULT_COLLISION_MARGIN, AM_DEFAULT);
+    ATTRIBUTE("CustomGeometry NodeID", int, customGeometryID_, 0, AM_DEFAULT | AM_NODEID);
 }
 
 void CollisionShape::OnSetAttribute(const AttributeInfo& attr, const Variant& src)
@@ -830,7 +830,7 @@ void CollisionShape::NotifyRigidBody(bool updateMass)
     }
 }
 
-void CollisionShape::SetModelAttr(ResourceRef value)
+void CollisionShape::SetModelAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     model_ = cache->GetResource<Model>(value.name_);

+ 12 - 12
Source/Engine/Physics/CollisionShape.h

@@ -73,7 +73,7 @@ struct TriangleMeshData : public CollisionGeometryData
     TriangleMeshData(CustomGeometry* custom);
     /// Destruct. Free geometry data.
     ~TriangleMeshData();
-    
+
     /// Bullet triangle mesh interface.
     TriangleMeshInterface* meshInterface_;
     /// Bullet triangle mesh collision shape.
@@ -91,10 +91,10 @@ struct ConvexData : public CollisionGeometryData
     ConvexData(CustomGeometry* custom);
     /// Destruct. Free geometry data.
     ~ConvexData();
-    
+
     /// Build the convex hull from vertices.
     void BuildHull(const PODVector<Vector3>& vertices);
-    
+
     /// Vertex data.
     SharedArrayPtr<Vector3> vertexData_;
     /// Number of vertices.
@@ -112,7 +112,7 @@ struct HeightfieldData : public CollisionGeometryData
     HeightfieldData(Terrain* terrain);
     /// Destruct. Free geometry data.
     ~HeightfieldData();
-    
+
     /// Height data.
     SharedArrayPtr<float> heightData_;
     /// Vertex spacing.
@@ -129,7 +129,7 @@ struct HeightfieldData : public CollisionGeometryData
 class URHO3D_API CollisionShape : public Component
 {
     OBJECT(CollisionShape);
-    
+
 public:
     /// Construct.
     CollisionShape(Context* context);
@@ -137,7 +137,7 @@ public:
     virtual ~CollisionShape();
     /// Register object factory.
     static void RegisterObject(Context* context);
-    
+
     /// Handle attribute write access.
     virtual void OnSetAttribute(const AttributeInfo& attr, const Variant& src);
     /// Apply attribute changes that can not be applied immediately. Called after scene load or a network update.
@@ -146,7 +146,7 @@ public:
     virtual void OnSetEnabled();
     /// Visualize the component as debug geometry.
     virtual void DrawDebugGeometry(DebugRenderer* debug, bool depthTest);
-    
+
     /// Set as a box.
     void SetBox(const Vector3& size, const Vector3& position = Vector3::ZERO, const Quaternion& rotation = Quaternion::IDENTITY);
     /// Set as a sphere.
@@ -185,7 +185,7 @@ public:
     void SetModel(Model* model);
     /// Set model LOD level.
     void SetLodLevel(unsigned lodLevel);
-    
+
     /// Return Bullet collision shape.
     btCollisionShape* GetCollisionShape() const { return shape_; }
     /// Return the shared geometry data.
@@ -208,22 +208,22 @@ public:
     unsigned GetLodLevel() const { return lodLevel_; }
     /// Return world-space bounding box.
     BoundingBox GetWorldBoundingBox() const;
-    
+
     /// Update the new collision shape to the RigidBody.
     void NotifyRigidBody(bool updateMass = true);
     /// Set model attribute.
-    void SetModelAttr(ResourceRef value);
+    void SetModelAttr(const ResourceRef& value);
     /// Return model attribute.
     ResourceRef GetModelAttr() const;
     /// Release the collision shape.
     void ReleaseShape();
-    
+
 protected:
     /// Handle node being assigned.
     virtual void OnNodeSet(Node* node);
     /// Handle node transform being dirtied.
     virtual void OnMarkedDirty(Node* node);
-    
+
 private:
     /// Find the parent rigid body component and return its compound collision shape.
     btCompoundShape* GetParentCompoundShape();

+ 12 - 12
Source/Engine/Physics/Constraint.cpp

@@ -82,18 +82,18 @@ void Constraint::RegisterObject(Context* context)
 {
     context->RegisterFactory<Constraint>(PHYSICS_CATEGORY);
 
-    ACCESSOR_ATTRIBUTE(Constraint, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
-    ENUM_ATTRIBUTE(Constraint, "Constraint Type", constraintType_, typeNames, CONSTRAINT_POINT, AM_DEFAULT);
-    ATTRIBUTE(Constraint, VAR_VECTOR3, "Position", position_, Vector3::ZERO, AM_DEFAULT);
-    ATTRIBUTE(Constraint, VAR_QUATERNION, "Rotation", rotation_, Quaternion::IDENTITY, AM_DEFAULT);
-    ATTRIBUTE(Constraint, VAR_VECTOR3, "Other Body Position", otherPosition_, Vector3::ZERO, AM_DEFAULT);
-    ATTRIBUTE(Constraint, VAR_QUATERNION, "Other Body Rotation", otherRotation_, Quaternion::IDENTITY, AM_DEFAULT);
-    ATTRIBUTE(Constraint, VAR_INT, "Other Body NodeID", otherBodyNodeID_, 0, AM_DEFAULT | AM_NODEID);
-    REF_ACCESSOR_ATTRIBUTE(Constraint, VAR_VECTOR2, "High Limit", GetHighLimit, SetHighLimit, Vector2, Vector2::ZERO, AM_DEFAULT);
-    REF_ACCESSOR_ATTRIBUTE(Constraint, VAR_VECTOR2, "Low Limit", GetLowLimit, SetLowLimit, Vector2, Vector2::ZERO, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Constraint, VAR_FLOAT, "ERP Parameter", GetERP, SetERP, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Constraint, VAR_FLOAT, "CFM Parameter", GetCFM, SetCFM, float, 0.0f, AM_DEFAULT);
-    ATTRIBUTE(Constraint, VAR_BOOL, "Disable Collision", disableCollision_, false, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
+    ENUM_ATTRIBUTE("Constraint Type", constraintType_, typeNames, CONSTRAINT_POINT, AM_DEFAULT);
+    ATTRIBUTE("Position", Vector3, position_, Vector3::ZERO, AM_DEFAULT);
+    ATTRIBUTE("Rotation", Quaternion, rotation_, Quaternion::IDENTITY, AM_DEFAULT);
+    ATTRIBUTE("Other Body Position", Vector3, otherPosition_, Vector3::ZERO, AM_DEFAULT);
+    ATTRIBUTE("Other Body Rotation", Quaternion, otherRotation_, Quaternion::IDENTITY, AM_DEFAULT);
+    ATTRIBUTE("Other Body NodeID", int, otherBodyNodeID_, 0, AM_DEFAULT | AM_NODEID);
+    ACCESSOR_ATTRIBUTE("High Limit", GetHighLimit, SetHighLimit, Vector2, Vector2::ZERO, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Low Limit", GetLowLimit, SetLowLimit, Vector2, Vector2::ZERO, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("ERP Parameter", GetERP, SetERP, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("CFM Parameter", GetCFM, SetCFM, float, 0.0f, AM_DEFAULT);
+    ATTRIBUTE("Disable Collision", bool, disableCollision_, false, AM_DEFAULT);
 }
 
 void Constraint::OnSetAttribute(const AttributeInfo& attr, const Variant& src)

+ 21 - 21
Source/Engine/Physics/PhysicsWorld.cpp

@@ -179,14 +179,14 @@ void PhysicsWorld::RegisterObject(Context* context)
 {
     context->RegisterFactory<PhysicsWorld>(SUBSYSTEM_CATEGORY);
 
-    ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_VECTOR3, "Gravity", GetGravity, SetGravity, Vector3, DEFAULT_GRAVITY, AM_DEFAULT);
-    ATTRIBUTE(PhysicsWorld, VAR_INT, "Physics FPS", fps_, DEFAULT_FPS, AM_DEFAULT);
-    ATTRIBUTE(PhysicsWorld, VAR_INT, "Max Substeps", maxSubSteps_, 0, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_INT, "Solver Iterations", GetNumIterations, SetNumIterations, int, 10, AM_DEFAULT);
-    ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Net Max Angular Vel.", maxNetworkAngularVelocity_, DEFAULT_MAX_NETWORK_ANGULAR_VELOCITY, AM_DEFAULT);
-    ATTRIBUTE(PhysicsWorld, VAR_BOOL, "Interpolation", interpolation_, true, AM_FILE);
-    ATTRIBUTE(PhysicsWorld, VAR_BOOL, "Internal Edge Utility", internalEdge_, true, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_BOOL, "Split Impulse", GetSplitImpulse, SetSplitImpulse, bool, false, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Gravity", GetGravity, SetGravity, Vector3, DEFAULT_GRAVITY, AM_DEFAULT);
+    ATTRIBUTE("Physics FPS", int, fps_, DEFAULT_FPS, AM_DEFAULT);
+    ATTRIBUTE("Max Substeps", int, maxSubSteps_, 0, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Solver Iterations", GetNumIterations, SetNumIterations, int, 10, AM_DEFAULT);
+    ATTRIBUTE("Net Max Angular Vel.", float, maxNetworkAngularVelocity_, DEFAULT_MAX_NETWORK_ANGULAR_VELOCITY, AM_DEFAULT);
+    ATTRIBUTE("Interpolation", bool, interpolation_, true, AM_FILE);
+    ATTRIBUTE("Internal Edge Utility", bool, internalEdge_, true, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Split Impulse", GetSplitImpulse, SetSplitImpulse, bool, false, AM_DEFAULT);
 }
 
 bool PhysicsWorld::isVisible(const btVector3& aabbMin, const btVector3& aabbMax)
@@ -226,7 +226,7 @@ void PhysicsWorld::drawContactPoint(const btVector3& pointOnB, const btVector3&
 }
 
 void PhysicsWorld::draw3dText(const btVector3& location, const char* textString)
-{ 
+{
 }
 
 void PhysicsWorld::Update(float timeStep)
@@ -242,7 +242,7 @@ void PhysicsWorld::Update(float timeStep)
     }
     else if (maxSubSteps_ > 0)
         maxSubSteps = Min(maxSubSteps, maxSubSteps_);
-    
+
     delayedWorldTransforms_.Clear();
 
     if (interpolation_)
@@ -284,14 +284,14 @@ void PhysicsWorld::UpdateCollisions()
 void PhysicsWorld::SetFps(int fps)
 {
     fps_ = Clamp(fps, 1, 1000);
-    
+
     MarkNetworkUpdate();
 }
 
-void PhysicsWorld::SetGravity(Vector3 gravity)
+void PhysicsWorld::SetGravity(const Vector3& gravity)
 {
     world_->setGravity(ToBtVector3(gravity));
-    
+
     MarkNetworkUpdate();
 }
 
@@ -305,7 +305,7 @@ void PhysicsWorld::SetNumIterations(int num)
 {
     num = Clamp(num, 1, MAX_SOLVER_ITERATIONS);
     world_->getSolverInfo().m_numIterations = num;
-    
+
     MarkNetworkUpdate();
 }
 
@@ -317,21 +317,21 @@ void PhysicsWorld::SetInterpolation(bool enable)
 void PhysicsWorld::SetInternalEdge(bool enable)
 {
     internalEdge_ = enable;
-    
+
     MarkNetworkUpdate();
 }
 
 void PhysicsWorld::SetSplitImpulse(bool enable)
 {
     world_->getSolverInfo().m_splitImpulse = enable;
-    
+
     MarkNetworkUpdate();
 }
 
 void PhysicsWorld::SetMaxNetworkAngularVelocity(float velocity)
 {
     maxNetworkAngularVelocity_ = Clamp(velocity, 1.0f, 32767.0f);
-    
+
     MarkNetworkUpdate();
 }
 
@@ -427,7 +427,7 @@ void PhysicsWorld::ConvexCast(PhysicsRaycastResult& result, CollisionShape* shap
         result.distance_ = M_INFINITY;
         return;
     }
-    
+
     // If shape is attached in a rigidbody, set its collision group temporarily to 0 to make sure it is not returned in the sweep result
     RigidBody* bodyComp = shape->GetComponent<RigidBody>();
     btRigidBody* body = bodyComp ? bodyComp->GetBody() : (btRigidBody*)0;
@@ -457,7 +457,7 @@ void PhysicsWorld::ConvexCast(PhysicsRaycastResult& result, btCollisionShape* sh
         result.distance_ = M_INFINITY;
         return;
     }
-    
+
     if (!shape->isConvex())
     {
         LOGERROR("Can not use non-convex collision shape for convex cast");
@@ -467,7 +467,7 @@ void PhysicsWorld::ConvexCast(PhysicsRaycastResult& result, btCollisionShape* sh
         result.distance_ = M_INFINITY;
         return;
     }
-    
+
     PROFILE(PhysicsConvexCast);
 
     btCollisionWorld::ClosestConvexResultCallback convexCallback(ToBtVector3(startPos), ToBtVector3(endPos));
@@ -715,7 +715,7 @@ void PhysicsWorld::SendCollisionEvents()
     currentCollisions_.Clear();
     physicsCollisionData_.Clear();
     nodeCollisionData_.Clear();
-    
+
     int numManifolds = collisionDispatcher_->getNumManifolds();
 
     if (numManifolds)

+ 3 - 3
Source/Engine/Physics/PhysicsWorld.h

@@ -67,7 +67,7 @@ struct URHO3D_API PhysicsRaycastResult
 
     /// Test for inequality, added to prevent GCC from complaining.
     bool operator != (const PhysicsRaycastResult& rhs) const { return position_ != rhs.position_ || normal_ != rhs.normal_ || distance_ != rhs.distance_ || body_ != rhs.body_; }
-    
+
     /// Hit worldspace position.
     Vector3 position_;
     /// Hit worldspace normal.
@@ -133,7 +133,7 @@ public:
     /// Set simulation substeps per second.
     void SetFps(int fps);
     /// Set gravity.
-    void SetGravity(Vector3 gravity);
+    void SetGravity(const Vector3& gravity);
     /// Set maximum number of physics substeps per frame. 0 (default) is unlimited. Positive values cap the amount. Use a negative value to enable an adaptive timestep. This may cause inconsistent physics behavior.
     void SetMaxSubSteps(int num);
     /// Set number of constraint solver iterations.
@@ -164,7 +164,7 @@ public:
     void GetRigidBodies(PODVector<RigidBody*>& result, const BoundingBox& box, unsigned collisionMask = M_MAX_UNSIGNED);
     /// Return rigid bodies that have been in collision with a specific body on the last simulation step.
     void GetRigidBodies(PODVector<RigidBody*>& result, const RigidBody* body);
-    
+
     /// Return gravity.
     Vector3 GetGravity() const;
     /// Return maximum number of physics substeps per frame.

+ 35 - 35
Source/Engine/Physics/RigidBody.cpp

@@ -102,33 +102,33 @@ void RigidBody::RegisterObject(Context* context)
 {
     context->RegisterFactory<RigidBody>(PHYSICS_CATEGORY);
 
-    ACCESSOR_ATTRIBUTE(RigidBody, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(RigidBody, VAR_QUATERNION, "Physics Rotation", GetRotation, SetRotation, Quaternion, Quaternion::IDENTITY, AM_FILE | AM_NOEDIT);
-    ACCESSOR_ATTRIBUTE(RigidBody, VAR_VECTOR3, "Physics Position", GetPosition, SetPosition, Vector3, Vector3::ZERO, AM_FILE | AM_NOEDIT);
-    ATTRIBUTE(RigidBody, VAR_FLOAT, "Mass", mass_, DEFAULT_MASS, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(RigidBody, VAR_FLOAT, "Friction", GetFriction, SetFriction, float, DEFAULT_FRICTION, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(RigidBody, VAR_VECTOR3, "Anisotropic Friction", GetAnisotropicFriction, SetAnisotropicFriction, Vector3, Vector3::ONE, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(RigidBody, VAR_FLOAT, "Rolling Friction", GetRollingFriction, SetRollingFriction, float, DEFAULT_ROLLING_FRICTION, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(RigidBody, VAR_FLOAT, "Restitution", GetRestitution, SetRestitution, float, DEFAULT_RESTITUTION, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(RigidBody, VAR_VECTOR3, "Linear Velocity", GetLinearVelocity, SetLinearVelocity, Vector3, Vector3::ZERO, AM_DEFAULT | AM_LATESTDATA);
-    ACCESSOR_ATTRIBUTE(RigidBody, VAR_VECTOR3, "Angular Velocity", GetAngularVelocity, SetAngularVelocity, Vector3, Vector3::ZERO, AM_FILE);
-    ACCESSOR_ATTRIBUTE(RigidBody, VAR_VECTOR3, "Linear Factor", GetLinearFactor, SetLinearFactor, Vector3, Vector3::ONE, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(RigidBody, VAR_VECTOR3, "Angular Factor", GetAngularFactor, SetAngularFactor, Vector3, Vector3::ONE, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(RigidBody, VAR_FLOAT, "Linear Damping", GetLinearDamping, SetLinearDamping, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(RigidBody, VAR_FLOAT, "Angular Damping", GetAngularDamping, SetAngularDamping, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(RigidBody, VAR_FLOAT, "Linear Rest Threshold", GetLinearRestThreshold, SetLinearRestThreshold, float, 0.8f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(RigidBody, VAR_FLOAT, "Angular Rest Threshold", GetAngularRestThreshold, SetAngularRestThreshold, float, 1.0f, AM_DEFAULT);
-    ATTRIBUTE(RigidBody, VAR_INT, "Collision Layer", collisionLayer_, DEFAULT_COLLISION_LAYER, AM_DEFAULT);
-    ATTRIBUTE(RigidBody, VAR_INT, "Collision Mask", collisionMask_, DEFAULT_COLLISION_MASK, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(RigidBody, VAR_FLOAT, "Contact Threshold", GetContactProcessingThreshold, SetContactProcessingThreshold, float, BT_LARGE_FLOAT, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(RigidBody, VAR_FLOAT, "CCD Radius", GetCcdRadius, SetCcdRadius, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(RigidBody, VAR_FLOAT, "CCD Motion Threshold", GetCcdMotionThreshold, SetCcdMotionThreshold, float, 0.0f, AM_DEFAULT);
-    REF_ACCESSOR_ATTRIBUTE(RigidBody, VAR_BUFFER, "Network Angular Velocity", GetNetAngularVelocityAttr, SetNetAngularVelocityAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_NET | AM_LATESTDATA | AM_NOEDIT);
-    ENUM_ATTRIBUTE(RigidBody, "Collision Event Mode", collisionEventMode_, collisionEventModeNames, COLLISION_ACTIVE, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(RigidBody, VAR_BOOL, "Use Gravity", GetUseGravity, SetUseGravity, bool, true, AM_DEFAULT);
-    ATTRIBUTE(RigidBody, VAR_BOOL, "Is Kinematic", kinematic_, false, AM_DEFAULT);
-    ATTRIBUTE(RigidBody, VAR_BOOL, "Is Trigger", trigger_, false, AM_DEFAULT);
-    REF_ACCESSOR_ATTRIBUTE(RigidBody, VAR_VECTOR3, "Gravity Override", GetGravityOverride, SetGravityOverride, Vector3, Vector3::ZERO, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Physics Rotation", GetRotation, SetRotation, Quaternion, Quaternion::IDENTITY, AM_FILE | AM_NOEDIT);
+    MIXED_ACCESSOR_ATTRIBUTE("Physics Position", GetPosition, SetPosition, Vector3, Vector3::ZERO, AM_FILE | AM_NOEDIT);
+    ATTRIBUTE("Mass", float, mass_, DEFAULT_MASS, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Friction", GetFriction, SetFriction, float, DEFAULT_FRICTION, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Anisotropic Friction", GetAnisotropicFriction, SetAnisotropicFriction, Vector3, Vector3::ONE, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Rolling Friction", GetRollingFriction, SetRollingFriction, float, DEFAULT_ROLLING_FRICTION, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Restitution", GetRestitution, SetRestitution, float, DEFAULT_RESTITUTION, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Linear Velocity", GetLinearVelocity, SetLinearVelocity, Vector3, Vector3::ZERO, AM_DEFAULT | AM_LATESTDATA);
+    MIXED_ACCESSOR_ATTRIBUTE("Angular Velocity", GetAngularVelocity, SetAngularVelocity, Vector3, Vector3::ZERO, AM_FILE);
+    MIXED_ACCESSOR_ATTRIBUTE("Linear Factor", GetLinearFactor, SetLinearFactor, Vector3, Vector3::ONE, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Angular Factor", GetAngularFactor, SetAngularFactor, Vector3, Vector3::ONE, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Linear Damping", GetLinearDamping, SetLinearDamping, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Angular Damping", GetAngularDamping, SetAngularDamping, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Linear Rest Threshold", GetLinearRestThreshold, SetLinearRestThreshold, float, 0.8f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Angular Rest Threshold", GetAngularRestThreshold, SetAngularRestThreshold, float, 1.0f, AM_DEFAULT);
+    ATTRIBUTE("Collision Layer", int, collisionLayer_, DEFAULT_COLLISION_LAYER, AM_DEFAULT);
+    ATTRIBUTE("Collision Mask", int, collisionMask_, DEFAULT_COLLISION_MASK, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Contact Threshold", GetContactProcessingThreshold, SetContactProcessingThreshold, float, BT_LARGE_FLOAT, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("CCD Radius", GetCcdRadius, SetCcdRadius, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("CCD Motion Threshold", GetCcdMotionThreshold, SetCcdMotionThreshold, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Network Angular Velocity", GetNetAngularVelocityAttr, SetNetAngularVelocityAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_NET | AM_LATESTDATA | AM_NOEDIT);
+    ENUM_ATTRIBUTE("Collision Event Mode", collisionEventMode_, collisionEventModeNames, COLLISION_ACTIVE, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Use Gravity", GetUseGravity, SetUseGravity, bool, true, AM_DEFAULT);
+    ATTRIBUTE("Is Kinematic", bool, kinematic_, false, AM_DEFAULT);
+    ATTRIBUTE("Is Trigger", bool, trigger_, false, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Gravity Override", GetGravityOverride, SetGravityOverride, Vector3, Vector3::ZERO, AM_DEFAULT);
 }
 
 void RigidBody::OnSetAttribute(const AttributeInfo& attr, const Variant& src)
@@ -228,7 +228,7 @@ void RigidBody::SetMass(float mass)
     }
 }
 
-void RigidBody::SetPosition(Vector3 position)
+void RigidBody::SetPosition(const Vector3& position)
 {
     if (body_)
     {
@@ -245,7 +245,7 @@ void RigidBody::SetPosition(Vector3 position)
     }
 }
 
-void RigidBody::SetRotation(Quaternion rotation)
+void RigidBody::SetRotation(const Quaternion& rotation)
 {
     if (body_)
     {
@@ -286,7 +286,7 @@ void RigidBody::SetTransform(const Vector3& position, const Quaternion& rotation
     }
 }
 
-void RigidBody::SetLinearVelocity(Vector3 velocity)
+void RigidBody::SetLinearVelocity(const Vector3& velocity)
 {
     if (body_)
     {
@@ -297,7 +297,7 @@ void RigidBody::SetLinearVelocity(Vector3 velocity)
     }
 }
 
-void RigidBody::SetLinearFactor(Vector3 factor)
+void RigidBody::SetLinearFactor(const Vector3& factor)
 {
     if (body_)
     {
@@ -324,7 +324,7 @@ void RigidBody::SetLinearDamping(float damping)
     }
 }
 
-void RigidBody::SetAngularVelocity(Vector3 velocity)
+void RigidBody::SetAngularVelocity(const Vector3& velocity)
 {
     if (body_)
     {
@@ -335,7 +335,7 @@ void RigidBody::SetAngularVelocity(Vector3 velocity)
     }
 }
 
-void RigidBody::SetAngularFactor(Vector3 factor)
+void RigidBody::SetAngularFactor(const Vector3& factor)
 {
     if (body_)
     {
@@ -371,7 +371,7 @@ void RigidBody::SetFriction(float friction)
     }
 }
 
-void RigidBody::SetAnisotropicFriction(Vector3 friction)
+void RigidBody::SetAnisotropicFriction(const Vector3& friction)
 {
     if (body_)
     {
@@ -705,7 +705,7 @@ void RigidBody::ApplyWorldTransform(const Vector3& newWorldPosition, const Quate
     // where node is already null
     if (!node_ || !physicsWorld_)
         return;
-    
+
     physicsWorld_->SetApplyingTransforms(true);
 
     // Apply transform to the SmoothedTransform component instead of node transform if available

+ 15 - 15
Source/Engine/Physics/RigidBody.h

@@ -50,7 +50,7 @@ enum CollisionEventMode
 class URHO3D_API RigidBody : public Component, public btMotionState
 {
     OBJECT(RigidBody);
-    
+
 public:
     /// Construct.
     RigidBody(Context* context);
@@ -58,7 +58,7 @@ public:
     virtual ~RigidBody();
     /// Register object factory.
     static void RegisterObject(Context* context);
-    
+
     /// Handle attribute write access.
     virtual void OnSetAttribute(const AttributeInfo& attr, const Variant& src);
     /// Apply attribute changes that can not be applied immediately. Called after scene load or a network update.
@@ -71,27 +71,27 @@ public:
     virtual void setWorldTransform(const btTransform &worldTrans);
     /// Visualize the component as debug geometry.
     virtual void DrawDebugGeometry(DebugRenderer* debug, bool depthTest);
-    
+
     /// Set mass. Zero mass makes the body static.
     void SetMass(float mass);
     /// Set rigid body position in world space.
-    void SetPosition(Vector3 position);
+    void SetPosition(const Vector3& position);
     /// Set rigid body rotation in world space.
-    void SetRotation(Quaternion rotation);
+    void SetRotation(const Quaternion& rotation);
     /// Set rigid body position and rotation in world space as an atomic operation.
     void SetTransform(const Vector3& position, const Quaternion& rotation);
     /// Set linear velocity.
-    void SetLinearVelocity(Vector3 velocity);
+    void SetLinearVelocity(const Vector3& velocity);
     /// Set linear degrees of freedom. Use 1 to enable an axis or 0 to disable. Default is all axes enabled (1, 1, 1).
-    void SetLinearFactor(Vector3 factor);
+    void SetLinearFactor(const Vector3& factor);
     /// Set linear velocity deactivation threshold.
     void SetLinearRestThreshold(float threshold);
     /// Set linear velocity damping factor.
     void SetLinearDamping(float damping);
     /// Set angular velocity.
-    void SetAngularVelocity(Vector3 angularVelocity);
+    void SetAngularVelocity(const Vector3& angularVelocity);
     /// Set angular degrees of freedom. Use 1 to enable an axis or 0 to disable. Default is all axes enabled (1, 1, 1).
-    void SetAngularFactor(Vector3 factor);
+    void SetAngularFactor(const Vector3& factor);
     /// Set angular velocity deactivation threshold.
     void SetAngularRestThreshold(float threshold);
     /// Set angular velocity damping factor.
@@ -99,7 +99,7 @@ public:
     /// Set friction coefficient.
     void SetFriction(float friction);
     /// Set anisotropic friction.
-    void SetAnisotropicFriction(Vector3 friction);
+    void SetAnisotropicFriction(const Vector3& friction);
     /// Set rolling friction coefficient.
     void SetRollingFriction(float friction);
     /// Set restitution coefficient.
@@ -148,7 +148,7 @@ public:
     void DisableMassUpdate();
     /// Re-enable mass update and recalculate the mass/inertia by calling UpdateMass(). Call when collision shape changes are finished.
     void EnableMassUpdate();
-    
+
     /// Return physics world.
     PhysicsWorld* GetPhysicsWorld() const { return physicsWorld_; }
     /// Return Bullet rigid body.
@@ -213,7 +213,7 @@ public:
     CollisionEventMode GetCollisionEventMode() const { return collisionEventMode_; }
     /// Return colliding rigid bodies from the last simulation step.
     void GetCollidingBodies(PODVector<RigidBody*>& result) const;
-    
+
     /// Apply new world transform after a simulation step. Called internally.
     void ApplyWorldTransform(const Vector3& newWorldPosition, const Quaternion& newWorldRotation);
     /// Update mass and inertia to the Bullet rigid body.
@@ -230,13 +230,13 @@ public:
     void RemoveConstraint(Constraint* constraint);
     /// Remove the rigid body.
     void ReleaseBody();
-    
+
 protected:
     /// Handle node being assigned.
     virtual void OnNodeSet(Node* node);
     /// Handle node transform being dirtied.
     virtual void OnMarkedDirty(Node* node);
-    
+
 private:
     /// Create the rigid body, or re-add to the physics world with changed flags. Calls UpdateMass().
     void AddBodyToWorld();
@@ -246,7 +246,7 @@ private:
     void HandleTargetPosition(StringHash eventType, VariantMap& eventData);
     /// Handle SmoothedTransform target rotation update.
     void HandleTargetRotation(StringHash eventType, VariantMap& eventData);
-    
+
     /// Bullet rigid body.
     btRigidBody* body_;
     /// Bullet compound collision shape.

+ 2 - 2
Source/Engine/Scene/Animatable.cpp

@@ -69,7 +69,7 @@ Animatable::~Animatable()
 
 void Animatable::RegisterObject(Context* context)
 {
-    ACCESSOR_ATTRIBUTE(Animatable, VAR_RESOURCEREF, "Object Animation", GetObjectAnimationAttr, SetObjectAnimationAttr, ResourceRef, ResourceRef(ObjectAnimation::GetTypeStatic()), AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Object Animation", GetObjectAnimationAttr, SetObjectAnimationAttr, ResourceRef, ResourceRef(ObjectAnimation::GetTypeStatic()), AM_DEFAULT);
 }
 
 bool Animatable::LoadXML(const XMLElement& source, bool setInstanceDefault)
@@ -273,7 +273,7 @@ float Animatable::GetAttributeAnimationSpeed(const String& name) const
     return info ? info->GetSpeed() : 1.0f;
 }
 
-void Animatable::SetObjectAnimationAttr(ResourceRef value)
+void Animatable::SetObjectAnimationAttr(const ResourceRef& value)
 {
     if (!value.name_.Empty())
     {

+ 1 - 1
Source/Engine/Scene/Animatable.h

@@ -98,7 +98,7 @@ public:
     float GetAttributeAnimationSpeed(const String& name) const;
 
     /// Set object animation attribute.
-    void SetObjectAnimationAttr(ResourceRef value);
+    void SetObjectAnimationAttr(const ResourceRef& value);
     /// Return object animation attribute.
     ResourceRef GetObjectAnimationAttr() const;
 

+ 9 - 9
Source/Engine/Scene/Node.cpp

@@ -71,15 +71,15 @@ void Node::RegisterObject(Context* context)
 {
     context->RegisterFactory<Node>();
 
-    ACCESSOR_ATTRIBUTE(Node, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
-    REF_ACCESSOR_ATTRIBUTE(Node, VAR_STRING, "Name", GetName, SetName, String, String::EMPTY, AM_DEFAULT);
-    REF_ACCESSOR_ATTRIBUTE(Node, VAR_VECTOR3, "Position", GetPosition, SetPosition, Vector3, Vector3::ZERO, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(Node, VAR_QUATERNION, "Rotation", GetRotation, SetRotation, Quaternion, Quaternion::IDENTITY, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(Node, VAR_VECTOR3, "Scale", GetScale, SetScale, Vector3, Vector3::ONE, AM_DEFAULT);
-    ATTRIBUTE(Node, VAR_VARIANTMAP, "Variables", vars_, Variant::emptyVariantMap, AM_FILE); // Network replication of vars uses custom data
-    REF_ACCESSOR_ATTRIBUTE(Node, VAR_VECTOR3, "Network Position", GetNetPositionAttr, SetNetPositionAttr, Vector3, Vector3::ZERO, AM_NET | AM_LATESTDATA | AM_NOEDIT);
-    REF_ACCESSOR_ATTRIBUTE(Node, VAR_BUFFER, "Network Rotation", GetNetRotationAttr, SetNetRotationAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_NET | AM_LATESTDATA | AM_NOEDIT);
-    REF_ACCESSOR_ATTRIBUTE(Node, VAR_BUFFER, "Network Parent Node", GetNetParentAttr, SetNetParentAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_NET | AM_NOEDIT);
+    ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Name", GetName, SetName, String, String::EMPTY, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Position", GetPosition, SetPosition, Vector3, Vector3::ZERO, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Rotation", GetRotation, SetRotation, Quaternion, Quaternion::IDENTITY, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Scale", GetScale, SetScale, Vector3, Vector3::ONE, AM_DEFAULT);
+    ATTRIBUTE("Variables", VariantMap, vars_, Variant::emptyVariantMap, AM_FILE); // Network replication of vars uses custom data
+    ACCESSOR_ATTRIBUTE("Network Position", GetNetPositionAttr, SetNetPositionAttr, Vector3, Vector3::ZERO, AM_NET | AM_LATESTDATA | AM_NOEDIT);
+    ACCESSOR_ATTRIBUTE("Network Rotation", GetNetRotationAttr, SetNetRotationAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_NET | AM_LATESTDATA | AM_NOEDIT);
+    ACCESSOR_ATTRIBUTE("Network Parent Node", GetNetParentAttr, SetNetParentAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_NET | AM_NOEDIT);
 }
 
 bool Node::Load(Deserializer& source, bool setInstanceDefault)

+ 36 - 36
Source/Engine/Scene/Scene.cpp

@@ -95,17 +95,17 @@ void Scene::RegisterObject(Context* context)
 {
     context->RegisterFactory<Scene>();
 
-    REF_ACCESSOR_ATTRIBUTE(Scene, VAR_STRING, "Name", GetName, SetName, String, String::EMPTY, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Scene, VAR_FLOAT, "Time Scale", GetTimeScale, SetTimeScale, float, 1.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Scene, VAR_FLOAT, "Smoothing Constant", GetSmoothingConstant, SetSmoothingConstant, float, DEFAULT_SMOOTHING_CONSTANT, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Scene, VAR_FLOAT, "Snap Threshold", GetSnapThreshold, SetSnapThreshold, float, DEFAULT_SNAP_THRESHOLD, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Scene, VAR_FLOAT, "Elapsed Time", GetElapsedTime, SetElapsedTime, float, 0.0f, AM_FILE);
-    ATTRIBUTE(Scene, VAR_INT, "Next Replicated Node ID", replicatedNodeID_, FIRST_REPLICATED_ID, AM_FILE | AM_NOEDIT);
-    ATTRIBUTE(Scene, VAR_INT, "Next Replicated Component ID", replicatedComponentID_, FIRST_REPLICATED_ID, AM_FILE | AM_NOEDIT);
-    ATTRIBUTE(Scene, VAR_INT, "Next Local Node ID", localNodeID_, FIRST_LOCAL_ID, AM_FILE | AM_NOEDIT);
-    ATTRIBUTE(Scene, VAR_INT, "Next Local Component ID", localComponentID_, FIRST_LOCAL_ID, AM_FILE | AM_NOEDIT);
-    ATTRIBUTE(Scene, VAR_VARIANTMAP, "Variables", vars_, Variant::emptyVariantMap, AM_FILE); // Network replication of vars uses custom data
-    ACCESSOR_ATTRIBUTE(Scene, VAR_STRING, "Variable Names", GetVarNamesAttr, SetVarNamesAttr, String, String::EMPTY, AM_FILE | AM_NOEDIT);
+    ACCESSOR_ATTRIBUTE("Name", GetName, SetName, String, String::EMPTY, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Time Scale", GetTimeScale, SetTimeScale, float, 1.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Smoothing Constant", GetSmoothingConstant, SetSmoothingConstant, float, DEFAULT_SMOOTHING_CONSTANT, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Snap Threshold", GetSnapThreshold, SetSnapThreshold, float, DEFAULT_SNAP_THRESHOLD, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Elapsed Time", GetElapsedTime, SetElapsedTime, float, 0.0f, AM_FILE);
+    ATTRIBUTE("Next Replicated Node ID", int, replicatedNodeID_, FIRST_REPLICATED_ID, AM_FILE | AM_NOEDIT);
+    ATTRIBUTE("Next Replicated Component ID", int, replicatedComponentID_, FIRST_REPLICATED_ID, AM_FILE | AM_NOEDIT);
+    ATTRIBUTE("Next Local Node ID", int, localNodeID_, FIRST_LOCAL_ID, AM_FILE | AM_NOEDIT);
+    ATTRIBUTE("Next Local Component ID", int, localComponentID_, FIRST_LOCAL_ID, AM_FILE | AM_NOEDIT);
+    ATTRIBUTE("Variables", VariantMap, vars_, Variant::emptyVariantMap, AM_FILE); // Network replication of vars uses custom data
+    MIXED_ACCESSOR_ATTRIBUTE("Variable Names", GetVarNamesAttr, SetVarNamesAttr, String, String::EMPTY, AM_FILE | AM_NOEDIT);
 }
 
 bool Scene::Load(Deserializer& source, bool setInstanceDefault)
@@ -268,25 +268,25 @@ bool Scene::LoadAsync(File* file, LoadMode mode)
         LOGINFO("Loading scene from " + file->GetName());
         Clear();
     }
-    
+
     asyncLoading_ = true;
     asyncProgress_.file_ = file;
     asyncProgress_.mode_ = mode;
     asyncProgress_.loadedNodes_ = asyncProgress_.totalNodes_ = asyncProgress_.loadedResources_ = asyncProgress_.totalResources_ = 0;
     asyncProgress_.resources_.Clear();
-    
+
     if (mode > LOAD_RESOURCES_ONLY)
     {
         // Preload resources if appropriate, then return to the original position for loading the scene content
         if (mode != LOAD_SCENE)
         {
             PROFILE(FindResourcesToPreload);
-            
+
             unsigned currentPos = file->GetPosition();
             PreloadResources(file, isSceneFile);
             file->Seek(currentPos);
         }
-        
+
         // Store own old ID for resolving possible root node references
         unsigned nodeID = file->ReadUInt();
         resolver_.AddNode(nodeID, this);
@@ -297,14 +297,14 @@ bool Scene::LoadAsync(File* file, LoadMode mode)
             StopAsyncLoading();
             return false;
         }
-        
+
         // Then prepare to load child nodes in the async updates
         asyncProgress_.totalNodes_ = file->ReadVLE();
     }
     else
     {
         PROFILE(FindResourcesToPreload);
-        
+
         LOGINFO("Preloading resources from " + file->GetName());
         PreloadResources(file, isSceneFile);
     }
@@ -331,26 +331,26 @@ bool Scene::LoadAsyncXML(File* file, LoadMode mode)
         LOGINFO("Loading scene from " + file->GetName());
         Clear();
     }
-    
+
     asyncLoading_ = true;
     asyncProgress_.xmlFile_ = xml;
     asyncProgress_.file_ = file;
     asyncProgress_.mode_ = mode;
     asyncProgress_.loadedNodes_ = asyncProgress_.totalNodes_ = asyncProgress_.loadedResources_ = asyncProgress_.totalResources_ = 0;
     asyncProgress_.resources_.Clear();
-    
+
     if (mode > LOAD_RESOURCES_ONLY)
     {
         XMLElement rootElement = xml->GetRoot();
-        
+
         // Preload resources if appropriate
         if (mode != LOAD_SCENE)
         {
             PROFILE(FindResourcesToPreload);
-            
+
             PreloadResourcesXML(rootElement);
         }
-        
+
         // Store own old ID for resolving possible root node references
         unsigned nodeID = rootElement.GetInt("id");
         resolver_.AddNode(nodeID, this);
@@ -373,11 +373,11 @@ bool Scene::LoadAsyncXML(File* file, LoadMode mode)
     else
     {
         PROFILE(FindResourcesToPreload);
-        
+
         LOGINFO("Preloading resources from " + file->GetName());
         PreloadResourcesXML(xml->GetRoot());
     }
-    
+
     return true;
 }
 
@@ -583,7 +583,7 @@ float Scene::GetAsyncProgress() const
         return 1.0f;
     else
     {
-        return (float)(asyncProgress_.loadedNodes_ + asyncProgress_.loadedResources_) / (float)(asyncProgress_.totalNodes_ + 
+        return (float)(asyncProgress_.loadedNodes_ + asyncProgress_.loadedResources_) / (float)(asyncProgress_.totalNodes_ +
             asyncProgress_.totalResources_);
     }
 }
@@ -854,7 +854,7 @@ void Scene::ComponentRemoved(Component* component)
     component->SetID(0);
 }
 
-void Scene::SetVarNamesAttr(String value)
+void Scene::SetVarNamesAttr(const String& value)
 {
     Vector<String> varNames = value.Split(';');
 
@@ -963,7 +963,7 @@ void Scene::HandleUpdate(StringHash eventType, VariantMap& eventData)
 void Scene::HandleResourceBackgroundLoaded(StringHash eventType, VariantMap& eventData)
 {
     using namespace ResourceBackgroundLoaded;
-    
+
     if (asyncLoading_)
     {
         Resource* resource = static_cast<Resource*>(eventData[P_RESOURCE].GetPtr());
@@ -982,7 +982,7 @@ void Scene::UpdateAsyncLoading()
     // If resources left to load, do not load nodes yet
     if (asyncProgress_.loadedResources_ < asyncProgress_.totalResources_)
         return;
-    
+
     HiresTimer asyncLoadTimer;
 
     for (;;)
@@ -1070,14 +1070,14 @@ void Scene::FinishSaving(Serializer* dest) const
 void Scene::PreloadResources(File* file, bool isSceneFile)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
-    
+
     // Read node ID (not needed)
     /*unsigned nodeID = */file->ReadUInt();
 
     // Read Node or Scene attributes; these do not include any resources
     const Vector<AttributeInfo>* attributes = context_->GetAttributes(isSceneFile ? Scene::GetTypeStatic() : Node::GetTypeStatic());
     assert(attributes);
-    
+
     for (unsigned i = 0; i < attributes->Size(); ++i)
     {
         const AttributeInfo& attr = attributes->At(i);
@@ -1085,7 +1085,7 @@ void Scene::PreloadResources(File* file, bool isSceneFile)
             continue;
         Variant varValue = file->ReadVariant(attr.type_);
     }
-    
+
     // Read component attributes
     unsigned numComponents = file->ReadVLE();
     for (unsigned i = 0; i < numComponents; ++i)
@@ -1094,7 +1094,7 @@ void Scene::PreloadResources(File* file, bool isSceneFile)
         StringHash compType = compBuffer.ReadStringHash();
         // Read component ID (not needed)
         /*unsigned compID = */compBuffer.ReadUInt();
-        
+
         attributes = context_->GetAttributes(compType);
         if (attributes)
         {
@@ -1133,7 +1133,7 @@ void Scene::PreloadResources(File* file, bool isSceneFile)
              }
         }
     }
-    
+
     // Read child nodes
     unsigned numChildren = file->ReadVLE();
     for (unsigned i = 0; i < numChildren; ++i)
@@ -1143,7 +1143,7 @@ void Scene::PreloadResources(File* file, bool isSceneFile)
 void Scene::PreloadResourcesXML(const XMLElement& element)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
-    
+
     // Node or Scene attributes do not include any resources; therefore skip to the components
     XMLElement compElem = element.GetChild("component");
     while (compElem)
@@ -1191,7 +1191,7 @@ void Scene::PreloadResourcesXML(const XMLElement& element)
                                 }
                             }
                         }
-                        
+
                         startIndex = (i + 1) % attributes->Size();
                         break;
                     }
@@ -1201,7 +1201,7 @@ void Scene::PreloadResourcesXML(const XMLElement& element)
                         --attempts;
                     }
                 }
-                
+
                 attrElem = attrElem.GetNext("attribute");
             }
         }

+ 1 - 1
Source/Engine/Scene/Scene.h

@@ -195,7 +195,7 @@ public:
     /// Component removed. Remove from ID map.
     void ComponentRemoved(Component* component);
     /// Set node user variable reverse mappings.
-    void SetVarNamesAttr(String value);
+    void SetVarNamesAttr(const String& value);
     /// Return node user variable reverse mappings.
     String GetVarNamesAttr() const;
     /// Prepare network update by comparing attributes and marking replication states dirty as necessary.

+ 61 - 17
Source/Engine/Scene/Serializable.h

@@ -127,15 +127,15 @@ private:
     bool temporary_;
 };
 
-/// Template implementation of the attribute accessor invoke helper class.
-template <class T, class U> class AttributeAccessorImpl : public AttributeAccessor
+/// Template implementation of the enum attribute accessor invoke helper class.
+template <typename T, typename U> class EnumAttributeAccessorImpl : public AttributeAccessor
 {
 public:
     typedef U (T::*GetFunctionPtr)() const;
     typedef void (T::*SetFunctionPtr)(U);
 
     /// Construct with function pointers.
-    AttributeAccessorImpl(GetFunctionPtr getFunction, SetFunctionPtr setFunction) :
+    EnumAttributeAccessorImpl(GetFunctionPtr getFunction, SetFunctionPtr setFunction) :
         getFunction_(getFunction),
         setFunction_(setFunction)
     {
@@ -156,7 +156,7 @@ public:
     {
         assert(ptr);
         T* classPtr = static_cast<T*>(ptr);
-        (classPtr->*setFunction_)(value.Get<U>());
+        (classPtr->*setFunction_)((U)value.GetInt());
     }
 
     /// Class-specific pointer to getter function.
@@ -165,15 +165,59 @@ public:
     SetFunctionPtr setFunction_;
 };
 
-/// Template implementation of the attribute accessor invoke helper class using const references.
-template <class T, class U> class RefAttributeAccessorImpl : public AttributeAccessor
+/// Attribute trait (default use const reference for object type).
+template<typename T> struct AttributeTrait
+{
+    /// Get function return type.
+    typedef const T& ReturnType;
+    /// Set function parameter type.
+    typedef const T& ParameterType;    
+};
+
+/// Int attribute trait.
+template<> struct AttributeTrait<int>
+{
+    typedef int ReturnType;
+    typedef int ParameterType;    
+};
+
+/// unsigned attribute trait.
+template<> struct AttributeTrait<unsigned>
+{
+    typedef unsigned ReturnType;
+    typedef unsigned ParameterType;    
+};
+
+/// Bool attribute trait.
+template<> struct AttributeTrait<bool>
+{
+    typedef bool ReturnType; 
+    typedef bool ParameterType; 
+};
+
+/// Float attribute trait.
+template<> struct AttributeTrait<float>
+{
+    typedef float ReturnType;
+    typedef float ParameterType;    
+};
+
+/// Mixed attribute trait (use const reference for set function only).
+template<typename T> struct MixedAttributeTrait
+{
+    typedef T ReturnType;
+    typedef const T& ParameterType; 
+};
+
+/// Template implementation of the attribute accessor invoke helper class.
+template <typename T, typename U, typename Trait> class AttributeAccessorImpl : public AttributeAccessor
 {
 public:
-    typedef const U& (T::*GetFunctionPtr)() const;
-    typedef void (T::*SetFunctionPtr)(const U&);
+    typedef typename Trait ::ReturnType (T::*GetFunctionPtr)() const;
+    typedef void (T::*SetFunctionPtr)(typename Trait ::ParameterType);
 
     /// Construct with function pointers.
-    RefAttributeAccessorImpl(GetFunctionPtr getFunction, SetFunctionPtr setFunction) :
+    AttributeAccessorImpl(GetFunctionPtr getFunction, SetFunctionPtr setFunction) :
         getFunction_(getFunction),
         setFunction_(setFunction)
     {
@@ -203,13 +247,13 @@ public:
     SetFunctionPtr setFunction_;
 };
 
-#define COPY_BASE_ATTRIBUTES(className, sourceClassName) context->CopyBaseAttributes<sourceClassName, className>()
-#define REMOVE_ATTRIBUTE(className, name) context->RemoveAttribute<className>(name)
-#define ATTRIBUTE(className, type, name, variable, defaultValue, mode) context->RegisterAttribute<className>(Urho3D::AttributeInfo(type, name, offsetof(className, variable), defaultValue, mode))
-#define ENUM_ATTRIBUTE(className, name, variable, enumNames, defaultValue, mode) context->RegisterAttribute<className>(Urho3D::AttributeInfo(name, offsetof(className, variable), enumNames, defaultValue, mode))
-#define ACCESSOR_ATTRIBUTE(className, type, name, getFunction, setFunction, typeName, defaultValue, mode) context->RegisterAttribute<className>(Urho3D::AttributeInfo(type, name, new Urho3D::AttributeAccessorImpl<className, typeName>(&className::getFunction, &className::setFunction), defaultValue, mode))
-#define ENUM_ACCESSOR_ATTRIBUTE(className, name, getFunction, setFunction, typeName, enumNames, defaultValue, mode) context->RegisterAttribute<className>(Urho3D::AttributeInfo(name, new Urho3D::AttributeAccessorImpl<className, typeName>(&className::getFunction, &className::setFunction), enumNames, defaultValue, mode))
-#define REF_ACCESSOR_ATTRIBUTE(className, type, name, getFunction, setFunction, typeName, defaultValue, mode) context->RegisterAttribute<className>(Urho3D::AttributeInfo(type, name, new Urho3D::RefAttributeAccessorImpl<className, typeName>(&className::getFunction, &className::setFunction), defaultValue, mode))
-#define UPDATE_ATTRIBUTE_DEFAULT_VALUE(className, name, defaultValue) context->UpdateAttributeDefaultValue<className>(name, defaultValue)
+#define COPY_BASE_ATTRIBUTES(sourceClassName) context->CopyBaseAttributes<sourceClassName, ClassName>()
+#define REMOVE_ATTRIBUTE(name) context->RemoveAttribute<ClassName>(name)
+#define ENUM_ATTRIBUTE(name, variable, enumNames, defaultValue, mode) context->RegisterAttribute<ClassName>(Urho3D::AttributeInfo(name, offsetof(ClassName, variable), enumNames, defaultValue, mode))
+#define ATTRIBUTE(name, typeName, variable, defaultValue, mode) context->RegisterAttribute<ClassName>(Urho3D::AttributeInfo(GetVariantType<typeName >(), name, offsetof(ClassName, variable), defaultValue, mode))
+#define ENUM_ACCESSOR_ATTRIBUTE(name, getFunction, setFunction, typeName, enumNames, defaultValue, mode) context->RegisterAttribute<ClassName>(Urho3D::AttributeInfo(name, new Urho3D::EnumAttributeAccessorImpl<ClassName, typeName >(&ClassName::getFunction, &ClassName::setFunction), enumNames, defaultValue, mode))
+#define ACCESSOR_ATTRIBUTE(name, getFunction, setFunction, typeName, defaultValue, mode) context->RegisterAttribute<ClassName>(Urho3D::AttributeInfo(GetVariantType<typeName >(), name, new Urho3D::AttributeAccessorImpl<ClassName, typeName, AttributeTrait<typeName > >(&ClassName::getFunction, &ClassName::setFunction), defaultValue, mode))
+#define MIXED_ACCESSOR_ATTRIBUTE(name, getFunction, setFunction, typeName, defaultValue, mode) context->RegisterAttribute<ClassName>(Urho3D::AttributeInfo(GetVariantType<typeName >(), name, new Urho3D::AttributeAccessorImpl<ClassName, typeName, MixedAttributeTrait<typeName > >(&ClassName::getFunction, &ClassName::setFunction), defaultValue, mode))
+#define UPDATE_ATTRIBUTE_DEFAULT_VALUE(name, defaultValue) context->UpdateAttributeDefaultValue<ClassName>(name, defaultValue)
 
 }

+ 6 - 6
Source/Engine/Scene/SplinePath.cpp

@@ -50,12 +50,12 @@ void SplinePath::RegisterObject(Context* context)
 {
     context->RegisterFactory<SplinePath>(LOGIC_CATEGORY);
 
-    ENUM_ACCESSOR_ATTRIBUTE(SplinePath, "Interpolation Mode", GetInterpolationMode, SetInterpolationMode, InterpolationMode, interpolationModeNames, BEZIER_CURVE, AM_FILE);
-    ATTRIBUTE(SplinePath, VAR_FLOAT, "Speed", speed_, 1.f, AM_FILE);
-    ATTRIBUTE(SplinePath, VAR_FLOAT, "Traveled", traveled_, 0.f, AM_FILE | AM_NOEDIT);
-    ATTRIBUTE(SplinePath, VAR_FLOAT, "Elapsed Time", elapsedTime_, 0.f, AM_FILE | AM_NOEDIT);
-    ACCESSOR_ATTRIBUTE(SplinePath, VAR_INT, "Controlled", GetControlledIdAttr, SetControlledIdAttr, unsigned, 0, AM_FILE | AM_NODEID);
-    REF_ACCESSOR_ATTRIBUTE(SplinePath, VAR_VARIANTVECTOR, "Control Points", GetControlPointIdsAttr, SetControlPointIdsAttr, VariantVector, Variant::emptyVariantVector, AM_FILE | AM_NODEIDVECTOR);
+    ENUM_ACCESSOR_ATTRIBUTE("Interpolation Mode", GetInterpolationMode, SetInterpolationMode, InterpolationMode, interpolationModeNames, BEZIER_CURVE, AM_FILE);
+    ATTRIBUTE("Speed", float, speed_, 1.f, AM_FILE);
+    ATTRIBUTE("Traveled", float, traveled_, 0.f, AM_FILE | AM_NOEDIT);
+    ATTRIBUTE("Elapsed Time", float, elapsedTime_, 0.f, AM_FILE | AM_NOEDIT);
+    ACCESSOR_ATTRIBUTE("Controlled", GetControlledIdAttr, SetControlledIdAttr, unsigned, 0, AM_FILE | AM_NODEID);
+    ACCESSOR_ATTRIBUTE("Control Points", GetControlPointIdsAttr, SetControlPointIdsAttr, VariantVector, Variant::emptyVariantVector, AM_FILE | AM_NODEIDVECTOR);
 }
 
 void SplinePath::ApplyAttributes()

+ 12 - 12
Source/Engine/Script/PhysicsAPI.cpp

@@ -73,7 +73,7 @@ static void RegisterCollisionShape(asIScriptEngine* engine)
     engine->RegisterEnumValue("ShapeType", "SHAPE_TRIANGLEMESH", SHAPE_TRIANGLEMESH);
     engine->RegisterEnumValue("ShapeType", "SHAPE_CONVEXHULL", SHAPE_CONVEXHULL);
     engine->RegisterEnumValue("ShapeType", "SHAPE_TERRAIN", SHAPE_TERRAIN);
-    
+
     RegisterComponent<CollisionShape>(engine, "CollisionShape");
     engine->RegisterObjectMethod("CollisionShape", "void SetBox(const Vector3&in, const Vector3&in pos = Vector3(), const Quaternion&in rot = Quaternion())", asMETHOD(CollisionShape, SetBox), asCALL_THISCALL);
     engine->RegisterObjectMethod("CollisionShape", "void SetSphere(float, const Vector3&in pos = Vector3(), const Quaternion&in rot = Quaternion())", asMETHOD(CollisionShape, SetSphere), asCALL_THISCALL);
@@ -117,7 +117,7 @@ static void RegisterRigidBody(asIScriptEngine* engine)
     engine->RegisterEnumValue("CollisionEventMode", "COLLISION_NEVER", COLLISION_NEVER);
     engine->RegisterEnumValue("CollisionEventMode", "COLLISION_ACTIVE", COLLISION_ACTIVE);
     engine->RegisterEnumValue("CollisionEventMode", "COLLISION_ALWAYS", COLLISION_ALWAYS);
-    
+
     RegisterComponent<RigidBody>(engine, "RigidBody");
     engine->RegisterObjectMethod("RigidBody", "void SetTransform(const Vector3&in, const Quaternion&in)", asMETHOD(RigidBody, SetTransform), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "void SetCollisionLayerAndMask(uint, uint)", asMETHOD(RigidBody, SetCollisionLayerAndMask), asCALL_THISCALL);
@@ -135,21 +135,21 @@ static void RegisterRigidBody(asIScriptEngine* engine)
     engine->RegisterObjectMethod("RigidBody", "Vector3 GetVelocityAtPoint(const Vector3&in) const", asMETHOD(RigidBody, GetVelocityAtPoint), 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", "void set_position(Vector3)", asMETHOD(RigidBody, SetPosition), asCALL_THISCALL);
+    engine->RegisterObjectMethod("RigidBody", "void set_position(const Vector3&)", asMETHOD(RigidBody, SetPosition), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "Vector3 get_position() const", asMETHOD(RigidBody, GetPosition), asCALL_THISCALL);
-    engine->RegisterObjectMethod("RigidBody", "void set_rotation(Quaternion)", asMETHOD(RigidBody, SetRotation), asCALL_THISCALL);
+    engine->RegisterObjectMethod("RigidBody", "void set_rotation(const Quaternion&)", asMETHOD(RigidBody, SetRotation), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "Quaternion get_rotation() const", asMETHOD(RigidBody, GetRotation), asCALL_THISCALL);
-    engine->RegisterObjectMethod("RigidBody", "void set_linearVelocity(Vector3)", asMETHOD(RigidBody, SetLinearVelocity), asCALL_THISCALL);
+    engine->RegisterObjectMethod("RigidBody", "void set_linearVelocity(const Vector3&in)", asMETHOD(RigidBody, SetLinearVelocity), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "Vector3 get_linearVelocity() const", asMETHOD(RigidBody, GetLinearVelocity), asCALL_THISCALL);
-    engine->RegisterObjectMethod("RigidBody", "void set_linearFactor(Vector3)", asMETHOD(RigidBody, SetLinearFactor), asCALL_THISCALL);
+    engine->RegisterObjectMethod("RigidBody", "void set_linearFactor(const Vector3&)", asMETHOD(RigidBody, SetLinearFactor), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "Vector3 get_linearFactor() const", asMETHOD(RigidBody, GetLinearFactor), 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", "void set_linearDamping(float)", asMETHOD(RigidBody, SetLinearDamping), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "float get_linearDamping() const", asMETHOD(RigidBody, GetLinearDamping), asCALL_THISCALL);
-    engine->RegisterObjectMethod("RigidBody", "void set_angularVelocity(Vector3)", asMETHOD(RigidBody, SetAngularVelocity), asCALL_THISCALL);
+    engine->RegisterObjectMethod("RigidBody", "void set_angularVelocity(const Vector3&in)", asMETHOD(RigidBody, SetAngularVelocity), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "Vector3 get_angularVelocity() const", asMETHOD(RigidBody, GetAngularVelocity), asCALL_THISCALL);
-    engine->RegisterObjectMethod("RigidBody", "void set_angularFactor(Vector3)", asMETHOD(RigidBody, SetAngularFactor), asCALL_THISCALL);
+    engine->RegisterObjectMethod("RigidBody", "void set_angularFactor(const Vector3&)", asMETHOD(RigidBody, SetAngularFactor), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "Vector3 get_angularFactor() const", asMETHOD(RigidBody, GetAngularFactor), 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);
@@ -157,7 +157,7 @@ static void RegisterRigidBody(asIScriptEngine* engine)
     engine->RegisterObjectMethod("RigidBody", "float get_angularDamping() const", asMETHOD(RigidBody, GetAngularDamping), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "void set_friction(float)", asMETHOD(RigidBody, SetFriction), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "float get_friction() const", asMETHOD(RigidBody, GetFriction), asCALL_THISCALL);
-    engine->RegisterObjectMethod("RigidBody", "void set_anisotropicFriction(Vector3)", asMETHOD(RigidBody, SetAnisotropicFriction), asCALL_THISCALL);
+    engine->RegisterObjectMethod("RigidBody", "void set_anisotropicFriction(const Vector3&in)", asMETHOD(RigidBody, SetAnisotropicFriction), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "Vector3 get_anisotropicFriction() const", asMETHOD(RigidBody, GetAnisotropicFriction), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "void set_rollingFriction(float)", asMETHOD(RigidBody, SetRollingFriction), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "float get_rollingFriction() const", asMETHOD(RigidBody, GetRollingFriction), asCALL_THISCALL);
@@ -195,7 +195,7 @@ static void RegisterConstraint(asIScriptEngine* engine)
     engine->RegisterEnumValue("ConstraintType", "CONSTRAINT_HINGE", CONSTRAINT_HINGE);
     engine->RegisterEnumValue("ConstraintType", "CONSTRAINT_SLIDER", CONSTRAINT_SLIDER);
     engine->RegisterEnumValue("ConstraintType", "CONSTRAINT_CONETWIST", CONSTRAINT_CONETWIST);
-    
+
     RegisterComponent<Constraint>(engine, "Constraint");
     engine->RegisterObjectMethod("Constraint", "void set_constraintType(ConstraintType)", asMETHOD(Constraint, SetConstraintType), asCALL_THISCALL);
     engine->RegisterObjectMethod("Constraint", "ConstraintType get_constraintType() const", asMETHOD(Constraint, GetConstraintType), asCALL_THISCALL);
@@ -288,7 +288,7 @@ static void RegisterPhysicsWorld(asIScriptEngine* engine)
     engine->RegisterObjectProperty("PhysicsRaycastResult", "Vector3 normal", offsetof(PhysicsRaycastResult, normal_));
     engine->RegisterObjectProperty("PhysicsRaycastResult", "float distance", offsetof(PhysicsRaycastResult, distance_));
     engine->RegisterObjectMethod("PhysicsRaycastResult", "RigidBody@+ get_body() const", asFUNCTION(PhysicsRaycastResultGetRigidBody), asCALL_CDECL_OBJLAST);
-    
+
     RegisterComponent<PhysicsWorld>(engine, "PhysicsWorld");
     engine->RegisterObjectMethod("PhysicsWorld", "void Update(float)", asMETHOD(PhysicsWorld, Update), asCALL_THISCALL);
     engine->RegisterObjectMethod("PhysicsWorld", "void UpdateCollisions()", asMETHOD(PhysicsWorld, UpdateCollisions), asCALL_THISCALL);
@@ -303,7 +303,7 @@ static void RegisterPhysicsWorld(asIScriptEngine* engine)
     engine->RegisterObjectMethod("PhysicsWorld", "Array<RigidBody@>@ GetRigidBodies(RigidBody@+)", asFUNCTION(PhysicsWorldGetRigidBodiesBody), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("PhysicsWorld", "void DrawDebugGeometry(bool)", asMETHODPR(PhysicsWorld, DrawDebugGeometry, (bool), void), asCALL_THISCALL);
     engine->RegisterObjectMethod("PhysicsWorld", "void RemoveCachedGeometry(Model@+)", asMETHOD(PhysicsWorld, RemoveCachedGeometry), asCALL_THISCALL);
-    engine->RegisterObjectMethod("PhysicsWorld", "void set_gravity(Vector3)", asMETHOD(PhysicsWorld, SetGravity), asCALL_THISCALL);
+    engine->RegisterObjectMethod("PhysicsWorld", "void set_gravity(const Vector3&in)", asMETHOD(PhysicsWorld, SetGravity), asCALL_THISCALL);
     engine->RegisterObjectMethod("PhysicsWorld", "Vector3 get_gravity() const", asMETHOD(PhysicsWorld, GetGravity), asCALL_THISCALL);
     engine->RegisterObjectMethod("PhysicsWorld", "void set_maxSubSteps(int)", asMETHOD(PhysicsWorld, SetMaxSubSteps), asCALL_THISCALL);
     engine->RegisterObjectMethod("PhysicsWorld", "int get_maxSubSteps() const", asMETHOD(PhysicsWorld, GetMaxSubSteps), asCALL_THISCALL);

+ 10 - 10
Source/Engine/Script/ScriptInstance.cpp

@@ -80,12 +80,12 @@ void ScriptInstance::RegisterObject(Context* context)
 {
     context->RegisterFactory<ScriptInstance>(LOGIC_CATEGORY);
 
-    ACCESSOR_ATTRIBUTE(ScriptInstance, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(ScriptInstance, VAR_BUFFER, "Delayed Method Calls", GetDelayedCallsAttr, SetDelayedCallsAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_FILE | AM_NOEDIT);
-    ACCESSOR_ATTRIBUTE(ScriptInstance, VAR_RESOURCEREF, "Script File", GetScriptFileAttr, SetScriptFileAttr, ResourceRef, ResourceRef(ScriptFile::GetTypeStatic()), AM_DEFAULT);
-    REF_ACCESSOR_ATTRIBUTE(ScriptInstance, VAR_STRING, "Class Name", GetClassName, SetClassName, String, String::EMPTY, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(ScriptInstance, VAR_BUFFER, "Script Data", GetScriptDataAttr, SetScriptDataAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_FILE | AM_NOEDIT);
-    ACCESSOR_ATTRIBUTE(ScriptInstance, VAR_BUFFER, "Script Network Data", GetScriptNetworkDataAttr, SetScriptNetworkDataAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_NET | AM_NOEDIT);
+    ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Delayed Method Calls", GetDelayedCallsAttr, SetDelayedCallsAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_FILE | AM_NOEDIT);
+    MIXED_ACCESSOR_ATTRIBUTE("Script File", GetScriptFileAttr, SetScriptFileAttr, ResourceRef, ResourceRef(ScriptFile::GetTypeStatic()), AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Class Name", GetClassName, SetClassName, String, String::EMPTY, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Script Data", GetScriptDataAttr, SetScriptDataAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_FILE | AM_NOEDIT);
+    MIXED_ACCESSOR_ATTRIBUTE("Script Network Data", GetScriptNetworkDataAttr, SetScriptNetworkDataAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_NET | AM_NOEDIT);
 }
 
 void ScriptInstance::OnSetAttribute(const AttributeInfo& attr, const Variant& src)
@@ -353,13 +353,13 @@ void ScriptInstance::RemoveEventHandlersExcept(const PODVector<StringHash>& exce
     UnsubscribeFromAllEventsExcept(exceptions, true);
 }
 
-void ScriptInstance::SetScriptFileAttr(ResourceRef value)
+void ScriptInstance::SetScriptFileAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SetScriptFile(cache->GetResource<ScriptFile>(value.name_));
 }
 
-void ScriptInstance::SetDelayedCallsAttr(PODVector<unsigned char> value)
+void ScriptInstance::SetDelayedCallsAttr(const PODVector<unsigned char>& value)
 {
     MemoryBuffer buf(value);
     delayedCalls_.Resize(buf.ReadVLE());
@@ -376,7 +376,7 @@ void ScriptInstance::SetDelayedCallsAttr(PODVector<unsigned char> value)
         UpdateEventSubscription();
 }
 
-void ScriptInstance::SetScriptDataAttr(PODVector<unsigned char> data)
+void ScriptInstance::SetScriptDataAttr(const PODVector<unsigned char>& data)
 {
     if (scriptObject_ && methods_[METHOD_LOAD])
     {
@@ -387,7 +387,7 @@ void ScriptInstance::SetScriptDataAttr(PODVector<unsigned char> data)
     }
 }
 
-void ScriptInstance::SetScriptNetworkDataAttr(PODVector<unsigned char> data)
+void ScriptInstance::SetScriptNetworkDataAttr(const PODVector<unsigned char>& data)
 {
     if (scriptObject_ && methods_[METHOD_READNETWORKUPDATE])
     {

+ 11 - 11
Source/Engine/Script/ScriptInstance.h

@@ -57,7 +57,7 @@ enum ScriptInstanceMethod
 class URHO3D_API ScriptInstance : public Component, public ScriptEventListener
 {
     OBJECT(ScriptInstance);
-    
+
 public:
     /// Construct.
     ScriptInstance(Context* context);
@@ -65,7 +65,7 @@ public:
     virtual ~ScriptInstance();
     /// Register object factory.
     static void RegisterObject(Context* context);
-    
+
     /// Handle attribute write access.
     virtual void OnSetAttribute(const AttributeInfo& attr, const Variant& src);
     /// Handle attribute read access.
@@ -106,24 +106,24 @@ public:
     void DelayedExecute(float delay, bool repeat, const String& declaration, const VariantVector& parameters = Variant::emptyVariantVector);
     /// Clear pending delay-executed method calls. If empty declaration given, clears all.
     void ClearDelayedExecute(const String& declaration = String::EMPTY);
-    
+
     /// Return script file.
     ScriptFile* GetScriptFile() const { return scriptFile_; }
     /// Return script object.
     asIScriptObject* GetScriptObject() const { return scriptObject_; }
     /// Return class name.
     const String& GetClassName() const { return className_; }
-    
+
     /// Set script file attribute.
-    void SetScriptFileAttr(ResourceRef value);
+    void SetScriptFileAttr(const ResourceRef& value);
     /// Set delayed method calls attribute.
-    void SetDelayedCallsAttr(PODVector<unsigned char> value);
+    void SetDelayedCallsAttr(const PODVector<unsigned char>& value);
     /// Set fixed update time accumulator attribute.
     void SetFixedUpdateAccAttr(float value);
     /// Set script file serialization attribute by calling a script function.
-    void SetScriptDataAttr(PODVector<unsigned char> data);
+    void SetScriptDataAttr(const PODVector<unsigned char>& data);
     /// Set script network serialization attribute by calling a script function.
-    void SetScriptNetworkDataAttr(PODVector<unsigned char> data);
+    void SetScriptNetworkDataAttr(const PODVector<unsigned char>& data);
     /// Return script file attribute.
     ResourceRef GetScriptFileAttr() const;
     /// Return delayed method calls attribute.
@@ -134,11 +134,11 @@ public:
     PODVector<unsigned char> GetScriptDataAttr() const;
     /// Get script network serialization attribute by calling a script function.
     PODVector<unsigned char> GetScriptNetworkDataAttr() const;
-    
+
 protected:
     /// Handle node transform being dirtied.
     virtual void OnMarkedDirty(Node* node);
-    
+
 private:
     /// (Re)create the script object and check for supported methods if successfully created.
     void CreateObject();
@@ -170,7 +170,7 @@ private:
     void HandleScriptFileReload(StringHash eventType, VariantMap& eventData);
     /// Handle script file reload finished.
     void HandleScriptFileReloadFinished(StringHash eventType, VariantMap& eventData);
-    
+
     /// Script subsystem.
     SharedPtr<Script> script_;
     /// Script file.

+ 3 - 3
Source/Engine/Script/Urho2DAPI.cpp

@@ -285,7 +285,7 @@ static void RegisterTileMapLayer2D(asIScriptEngine* engine)
     engine->RegisterObjectMethod("TileMapLayer2D", "uint get_numObjects() const", asMETHOD(TileMapLayer2D, GetNumObjects), asCALL_THISCALL);
     engine->RegisterObjectMethod("TileMapLayer2D", "TileMapObject2D@ GetObject(uint) const", asMETHOD(TileMapLayer2D, GetObject), asCALL_THISCALL);
     engine->RegisterObjectMethod("TileMapLayer2D", "Node@ GetObjectNode(uint) const", asMETHOD(TileMapLayer2D, GetObjectNode), asCALL_THISCALL);
-    
+
     // For image layer only
     engine->RegisterObjectMethod("TileMapLayer2D", "Node@ get_imageNode() const", asMETHOD(TileMapLayer2D, GetImageNode), asCALL_THISCALL);
 }
@@ -315,7 +315,7 @@ static void RegisterRigidBody2D(asIScriptEngine* engine)
     engine->RegisterObjectMethod("RigidBody2D", "float get_mass() const", asMETHOD(RigidBody2D, GetMass), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody2D", "void set_inertia(float)", asMETHOD(RigidBody2D, SetInertia), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody2D", "float get_inertia() const", asMETHOD(RigidBody2D, GetInertia), asCALL_THISCALL);
-    engine->RegisterObjectMethod("RigidBody2D", "void set_massCenter(Vector2)", asMETHOD(RigidBody2D, SetMassCenter), asCALL_THISCALL);
+    engine->RegisterObjectMethod("RigidBody2D", "void set_massCenter(const Vector2&in)", asMETHOD(RigidBody2D, SetMassCenter), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody2D", "Vector2 get_massCenter() const", asMETHOD(RigidBody2D, GetMassCenter), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody2D", "void set_useFixtureMass(bool)", asMETHOD(RigidBody2D, SetUseFixtureMass), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody2D", "bool get_useFixtureMass() const", asMETHOD(RigidBody2D, GetUseFixtureMass), asCALL_THISCALL);
@@ -333,7 +333,7 @@ static void RegisterRigidBody2D(asIScriptEngine* engine)
     engine->RegisterObjectMethod("RigidBody2D", "float get_gravityScale() const", asMETHOD(RigidBody2D, GetGravityScale), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody2D", "void set_awake(bool)", asMETHOD(RigidBody2D, SetAwake), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody2D", "bool get_awake() const", asMETHOD(RigidBody2D, IsAwake), asCALL_THISCALL);
-    engine->RegisterObjectMethod("RigidBody2D", "void set_linearVelocity(Vector2)", asMETHOD(RigidBody2D, SetLinearVelocity), asCALL_THISCALL);
+    engine->RegisterObjectMethod("RigidBody2D", "void set_linearVelocity(const Vector2&in)", asMETHOD(RigidBody2D, SetLinearVelocity), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody2D", "Vector2 get_linearVelocity() const", asMETHOD(RigidBody2D, GetLinearVelocity), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody2D", "void ApplyForce(const Vector2&in, const Vector2&in, bool)", asMETHOD(RigidBody2D, ApplyForce), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody2D", "void ApplyForceToCenter(const Vector2&in, bool)", asMETHOD(RigidBody2D, ApplyForceToCenter), asCALL_THISCALL);

+ 9 - 14
Source/Engine/UI/BorderImage.cpp

@@ -34,11 +34,6 @@ namespace Urho3D
 extern const char* blendModeNames[];
 extern const char* UI_CATEGORY;
 
-template<> BlendMode Variant::Get<BlendMode>() const
-{
-    return (BlendMode)GetInt();
-}
-
 BorderImage::BorderImage(Context* context) :
     UIElement(context),
     imageRect_(IntRect::ZERO),
@@ -58,14 +53,14 @@ void BorderImage::RegisterObject(Context* context)
 {
     context->RegisterFactory<BorderImage>(UI_CATEGORY);
 
-    COPY_BASE_ATTRIBUTES(BorderImage, UIElement);
-    ACCESSOR_ATTRIBUTE(BorderImage, VAR_RESOURCEREF, "Texture", GetTextureAttr, SetTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(BorderImage, VAR_INTRECT, "Image Rect", GetImageRect, SetImageRect, IntRect, IntRect::ZERO, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(BorderImage, VAR_INTRECT, "Border", GetBorder, SetBorder, IntRect, IntRect::ZERO, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(BorderImage, VAR_INTRECT, "Image Border", GetImageBorder, SetImageBorder, IntRect, IntRect::ZERO, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(BorderImage, VAR_INTVECTOR2, "Hover Image Offset", GetHoverOffset, SetHoverOffset, IntVector2, IntVector2::ZERO, AM_FILE);
-    ACCESSOR_ATTRIBUTE(BorderImage, VAR_BOOL, "Tiled", IsTiled, SetTiled, bool, false, AM_FILE);
-    ENUM_ACCESSOR_ATTRIBUTE(BorderImage, "Blend Mode", GetBlendMode, SetBlendMode, BlendMode, blendModeNames, 0, AM_FILE);
+    COPY_BASE_ATTRIBUTES(UIElement);
+    MIXED_ACCESSOR_ATTRIBUTE("Texture", GetTextureAttr, SetTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_FILE);
+    ACCESSOR_ATTRIBUTE("Image Rect", GetImageRect, SetImageRect, IntRect, IntRect::ZERO, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Border", GetBorder, SetBorder, IntRect, IntRect::ZERO, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Image Border", GetImageBorder, SetImageBorder, IntRect, IntRect::ZERO, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Hover Image Offset", GetHoverOffset, SetHoverOffset, IntVector2, IntVector2::ZERO, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Tiled", IsTiled, SetTiled, bool, false, AM_FILE);
+    ENUM_ACCESSOR_ATTRIBUTE("Blend Mode", GetBlendMode, SetBlendMode, BlendMode, blendModeNames, 0, AM_FILE);
 }
 
 void BorderImage::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor)
@@ -198,7 +193,7 @@ void BorderImage::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vert
     hovering_ = false;
 }
 
-void BorderImage::SetTextureAttr(ResourceRef value)
+void BorderImage::SetTextureAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SetTexture(cache->GetResource<Texture2D>(value.name_));

+ 8 - 8
Source/Engine/UI/BorderImage.h

@@ -35,7 +35,7 @@ class Texture2D;
 class URHO3D_API BorderImage : public UIElement
 {
     OBJECT(BorderImage);
-    
+
 public:
     /// Construct.
     BorderImage(Context* context);
@@ -43,10 +43,10 @@ public:
     virtual ~BorderImage();
     /// Register object factory.
     static void RegisterObject(Context* context);
-    
+
     /// Return UI rendering batches.
     virtual void GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor);
-    
+
     /// Set texture.
     void SetTexture(Texture* texture);
     /// Set part of texture to use as the image.
@@ -65,7 +65,7 @@ public:
     void SetBlendMode(BlendMode mode);
     /// Set tiled mode.
     void SetTiled(bool enable);
-    
+
     /// Return texture.
     Texture* GetTexture() const { return texture_; }
     /// Return image rectangle.
@@ -80,16 +80,16 @@ public:
     BlendMode GetBlendMode() const { return blendMode_; }
     /// Return whether is tiled.
     bool IsTiled() const { return tiled_; }
-    
+
     /// Set texture attribute.
-    void SetTextureAttr(ResourceRef value);
+    void SetTextureAttr(const ResourceRef& value);
     /// Return texture attribute.
     ResourceRef GetTextureAttr() const;
-    
+
 protected:
     /// Return UI rendering batches with offset to image rectangle.
     void GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor, const IntVector2& offset);
-    
+
     /// Texture.
     SharedPtr<Texture> texture_;
     /// Image rectangle.

+ 7 - 7
Source/Engine/UI/Button.cpp

@@ -55,13 +55,13 @@ void Button::RegisterObject(Context* context)
 {
     context->RegisterFactory<Button>(UI_CATEGORY);
 
-    COPY_BASE_ATTRIBUTES(Button, BorderImage);
-    UPDATE_ATTRIBUTE_DEFAULT_VALUE(Button, "Is Enabled", true);
-    UPDATE_ATTRIBUTE_DEFAULT_VALUE(Button, "Focus Mode", FM_FOCUSABLE);
-    REF_ACCESSOR_ATTRIBUTE(Button, VAR_INTVECTOR2, "Pressed Image Offset", GetPressedOffset, SetPressedOffset, IntVector2, IntVector2::ZERO, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(Button, VAR_INTVECTOR2, "Pressed Child Offset", GetPressedChildOffset, SetPressedChildOffset, IntVector2, IntVector2::ZERO, AM_FILE);
-    ACCESSOR_ATTRIBUTE(Button, VAR_FLOAT, "Repeat Delay", GetRepeatDelay, SetRepeatDelay, float, 1.0f, AM_FILE);
-    ACCESSOR_ATTRIBUTE(Button, VAR_FLOAT, "Repeat Rate", GetRepeatRate, SetRepeatRate, float, 0.0f, AM_FILE);
+    COPY_BASE_ATTRIBUTES(BorderImage);
+    UPDATE_ATTRIBUTE_DEFAULT_VALUE("Is Enabled", true);
+    UPDATE_ATTRIBUTE_DEFAULT_VALUE("Focus Mode", FM_FOCUSABLE);
+    ACCESSOR_ATTRIBUTE("Pressed Image Offset", GetPressedOffset, SetPressedOffset, IntVector2, IntVector2::ZERO, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Pressed Child Offset", GetPressedChildOffset, SetPressedChildOffset, IntVector2, IntVector2::ZERO, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Repeat Delay", GetRepeatDelay, SetRepeatDelay, float, 1.0f, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Repeat Rate", GetRepeatRate, SetRepeatRate, float, 0.0f, AM_FILE);
 }
 
 void Button::Update(float timeStep)

+ 5 - 5
Source/Engine/UI/CheckBox.cpp

@@ -50,11 +50,11 @@ void CheckBox::RegisterObject(Context* context)
 {
     context->RegisterFactory<CheckBox>(UI_CATEGORY);
 
-    COPY_BASE_ATTRIBUTES(CheckBox, BorderImage);
-    UPDATE_ATTRIBUTE_DEFAULT_VALUE(CheckBox, "Is Enabled", true);
-    UPDATE_ATTRIBUTE_DEFAULT_VALUE(CheckBox, "Focus Mode", FM_FOCUSABLE_DEFOCUSABLE);
-    ACCESSOR_ATTRIBUTE(CheckBox, VAR_BOOL,"Is Checked", IsChecked, SetChecked, bool, false, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(CheckBox, VAR_INTVECTOR2,"Checked Image Offset", GetCheckedOffset, SetCheckedOffset, IntVector2, IntVector2::ZERO, AM_FILE);
+    COPY_BASE_ATTRIBUTES(BorderImage);
+    UPDATE_ATTRIBUTE_DEFAULT_VALUE("Is Enabled", true);
+    UPDATE_ATTRIBUTE_DEFAULT_VALUE("Focus Mode", FM_FOCUSABLE_DEFOCUSABLE);
+    ACCESSOR_ATTRIBUTE("Is Checked", IsChecked, SetChecked, bool, false, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Checked Image Offset", GetCheckedOffset, SetCheckedOffset, IntVector2, IntVector2::ZERO, AM_FILE);
 }
 
 void CheckBox::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor)

+ 10 - 10
Source/Engine/UI/Cursor.cpp

@@ -91,10 +91,10 @@ void Cursor::RegisterObject(Context* context)
 {
     context->RegisterFactory<Cursor>(UI_CATEGORY);
 
-    COPY_BASE_ATTRIBUTES(Cursor, BorderImage);
-    UPDATE_ATTRIBUTE_DEFAULT_VALUE(Cursor, "Priority", M_MAX_INT);
-    ACCESSOR_ATTRIBUTE(Cursor, VAR_BOOL, "Use System Shapes", GetUseSystemShapes, SetUseSystemShapes, bool, false, AM_FILE);
-    ACCESSOR_ATTRIBUTE(Cursor, VAR_VARIANTVECTOR, "Shapes", GetShapesAttr, SetShapesAttr, VariantVector, Variant::emptyVariantVector, AM_FILE);
+    COPY_BASE_ATTRIBUTES(BorderImage);
+    UPDATE_ATTRIBUTE_DEFAULT_VALUE("Priority", M_MAX_INT);
+    ACCESSOR_ATTRIBUTE("Use System Shapes", GetUseSystemShapes, SetUseSystemShapes, bool, false, AM_FILE);
+    MIXED_ACCESSOR_ATTRIBUTE("Shapes", GetShapesAttr, SetShapesAttr, VariantVector, Variant::emptyVariantVector, AM_FILE);
 }
 
 void Cursor::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor)
@@ -159,12 +159,12 @@ void Cursor::SetShape(CursorShape shape)
         return;
 
     shape_ = shape;
-    
+
     CursorShapeInfo& info = shapeInfos_[shape_];
     texture_ = info.texture_;
     imageRect_ = info.imageRect_;
     SetSize(info.imageRect_.Size());
-    
+
     // To avoid flicker, the UI subsystem will apply the OS shape once per frame. Exception: if we are using the
     // busy shape, set it immediately as we may block before that
     osShapeDirty_ = true;
@@ -182,7 +182,7 @@ void Cursor::SetUseSystemShapes(bool enable)
     }
 }
 
-void Cursor::SetShapesAttr(VariantVector value)
+void Cursor::SetShapesAttr(const VariantVector& value)
 {
     unsigned index = 0;
     if (!value.Size())
@@ -238,7 +238,7 @@ void Cursor::ApplyOSCursorShape()
         return;
 
     CursorShapeInfo& info = shapeInfos_[shape_];
-    
+
     // Remove existing SDL cursor if is not a system shape while we should be using those, or vice versa
     if (info.osCursor_ && info.systemDefined_ != useSystemShapes_)
     {
@@ -261,7 +261,7 @@ void Cursor::ApplyOSCursorShape()
         else if (info.image_)
         {
             SDL_Surface* surface = info.image_->GetSDLSurface(info.imageRect_);
-            
+
             if (surface)
             {
                 info.osCursor_ = SDL_CreateColorCursor(surface, info.hotSpot_.x_, info.hotSpot_.y_);
@@ -275,7 +275,7 @@ void Cursor::ApplyOSCursorShape()
 
     if (info.osCursor_)
         SDL_SetCursor(info.osCursor_);
-    
+
     osShapeDirty_ = false;
 #endif
 }

+ 8 - 8
Source/Engine/UI/Cursor.h

@@ -56,7 +56,7 @@ struct URHO3D_API CursorShapeInfo
         systemDefined_(false)
     {
     }
-    
+
     /// Image.
     SharedPtr<Image> image_;
     /// Texture.
@@ -75,7 +75,7 @@ struct URHO3D_API CursorShapeInfo
 class URHO3D_API Cursor : public BorderImage
 {
     OBJECT(Cursor);
-    
+
 public:
     /// Construct.
     Cursor(Context* context);
@@ -83,10 +83,10 @@ public:
     virtual ~Cursor();
     /// Register object factory.
     static void RegisterObject(Context* context);
-    
+
     /// Return UI rendering batches.
     virtual void GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor);
-    
+
     /// Define a shape.
     void DefineShape(CursorShape shape, Image* image, const IntRect& imageRect, const IntVector2& hotSpot);
     /// Set current shape.
@@ -97,18 +97,18 @@ public:
     CursorShape GetShape() const { return shape_; }
     /// Return whether is using system default shapes.
     bool GetUseSystemShapes() const { return useSystemShapes_; }
-    
+
     /// Set shapes attribute.
-    void SetShapesAttr(VariantVector value);
+    void SetShapesAttr(const VariantVector& value);
     /// Return shapes attribute.
     VariantVector GetShapesAttr() const;
     /// Apply pending OS cursor shape. Called by UI. No-op when the OS mouse pointer is not used.
     void ApplyOSCursorShape();
-    
+
 protected:
     /// Handle operating system mouse cursor visibility change event.
     void HandleMouseVisibleChanged(StringHash eventType, VariantMap& eventData);
-    
+
     /// Current shape index.
     CursorShape shape_;
     /// Shape definitions.

+ 4 - 4
Source/Engine/UI/DropDownList.cpp

@@ -72,10 +72,10 @@ void DropDownList::RegisterObject(Context* context)
 {
     context->RegisterFactory<DropDownList>(UI_CATEGORY);
 
-    COPY_BASE_ATTRIBUTES(DropDownList, Menu);
-    UPDATE_ATTRIBUTE_DEFAULT_VALUE(DropDownList, "Focus Mode", FM_FOCUSABLE_DEFOCUSABLE);
-    ACCESSOR_ATTRIBUTE(DropDownList, VAR_INT, "Selection", GetSelection, SetSelectionAttr, unsigned, 0, AM_FILE);
-    ACCESSOR_ATTRIBUTE(DropDownList, VAR_BOOL, "Resize Popup", GetResizePopup, SetResizePopup, bool, false, AM_FILE);
+    COPY_BASE_ATTRIBUTES(Menu);
+    UPDATE_ATTRIBUTE_DEFAULT_VALUE("Focus Mode", FM_FOCUSABLE_DEFOCUSABLE);
+    ACCESSOR_ATTRIBUTE("Selection", GetSelection, SetSelectionAttr, unsigned, 0, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Resize Popup", GetResizePopup, SetResizePopup, bool, false, AM_FILE);
 }
 
 void DropDownList::ApplyAttributes()

+ 10 - 10
Source/Engine/UI/LineEdit.cpp

@@ -74,16 +74,16 @@ void LineEdit::RegisterObject(Context* context)
 {
     context->RegisterFactory<LineEdit>(UI_CATEGORY);
 
-    COPY_BASE_ATTRIBUTES(LineEdit, BorderImage);
-    UPDATE_ATTRIBUTE_DEFAULT_VALUE(LineEdit, "Clip Children", true);
-    UPDATE_ATTRIBUTE_DEFAULT_VALUE(LineEdit, "Is Enabled", true);
-    UPDATE_ATTRIBUTE_DEFAULT_VALUE(LineEdit, "Focus Mode", FM_FOCUSABLE_DEFOCUSABLE);
-    ACCESSOR_ATTRIBUTE(LineEdit, VAR_INT, "Max Length", GetMaxLength, SetMaxLength, unsigned, 0, AM_FILE);
-    ACCESSOR_ATTRIBUTE(LineEdit, VAR_BOOL, "Is Cursor Movable", IsCursorMovable, SetCursorMovable, bool, true, AM_FILE);
-    ACCESSOR_ATTRIBUTE(LineEdit, VAR_BOOL, "Is Text Selectable", IsTextSelectable, SetTextSelectable, bool, true, AM_FILE);
-    ACCESSOR_ATTRIBUTE(LineEdit, VAR_BOOL, "Is Text Copyable", IsTextCopyable, SetTextCopyable, bool, true, AM_FILE);
-    ACCESSOR_ATTRIBUTE(LineEdit, VAR_FLOAT, "Cursor Blink Rate", GetCursorBlinkRate, SetCursorBlinkRate, float, 1.0f, AM_FILE);
-    ATTRIBUTE(LineEdit, VAR_INT, "Echo Character", echoCharacter_, 0, AM_FILE);
+    COPY_BASE_ATTRIBUTES(BorderImage);
+    UPDATE_ATTRIBUTE_DEFAULT_VALUE("Clip Children", true);
+    UPDATE_ATTRIBUTE_DEFAULT_VALUE("Is Enabled", true);
+    UPDATE_ATTRIBUTE_DEFAULT_VALUE("Focus Mode", FM_FOCUSABLE_DEFOCUSABLE);
+    ACCESSOR_ATTRIBUTE("Max Length", GetMaxLength, SetMaxLength, unsigned, 0, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Is Cursor Movable", IsCursorMovable, SetCursorMovable, bool, true, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Is Text Selectable", IsTextSelectable, SetTextSelectable, bool, true, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Is Text Copyable", IsTextCopyable, SetTextCopyable, bool, true, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Cursor Blink Rate", GetCursorBlinkRate, SetCursorBlinkRate, float, 1.0f, AM_FILE);
+    ATTRIBUTE("Echo Character", int, echoCharacter_, 0, AM_FILE);
 }
 
 void LineEdit::ApplyAttributes()

+ 17 - 13
Source/Engine/UI/ListView.cpp

@@ -44,11 +44,6 @@ static const char* highlightModes[] =
     0
 };
 
-template<> HighlightMode Variant::Get<HighlightMode>() const
-{
-    return (HighlightMode)GetInt();
-}
-
 static const StringHash expandedHash("Expanded");
 
 extern const char* UI_CATEGORY;
@@ -91,6 +86,9 @@ public:
         SubscribeToEvent(overlayContainer->GetParent(), E_VIEWCHANGED, HANDLER(HierarchyContainer, HandleViewChanged));
         SubscribeToEvent(E_UIMOUSECLICK, HANDLER(HierarchyContainer, HandleUIMouseClick));
     }
+    
+    /// Register object factory.
+    static void RegisterObject(Context* context);
 
     /// Handle layout updated by adjusting the position of the overlays.
     void HandleLayoutUpdated(StringHash eventType, VariantMap& eventData)
@@ -161,6 +159,11 @@ private:
     UIElement* overlayContainer_;
 };
 
+void HierarchyContainer::RegisterObject(Context* context)
+{
+    COPY_BASE_ATTRIBUTES(UIElement);
+}
+
 ListView::ListView(Context* context) :
     ScrollView(context),
     highlightMode_(HM_FOCUS),
@@ -191,14 +194,15 @@ void ListView::RegisterObject(Context* context)
 {
     context->RegisterFactory<ListView>(UI_CATEGORY);
 
-    COPY_BASE_ATTRIBUTES(HierarchyContainer, UIElement);
-    COPY_BASE_ATTRIBUTES(ListView, ScrollView);
-    ENUM_ACCESSOR_ATTRIBUTE(ListView, "Highlight Mode", GetHighlightMode, SetHighlightMode, HighlightMode, highlightModes, HM_FOCUS, AM_FILE);
-    ACCESSOR_ATTRIBUTE(ListView, VAR_BOOL, "Multiselect", GetMultiselect, SetMultiselect, bool, false, AM_FILE);
-    ACCESSOR_ATTRIBUTE(ListView, VAR_BOOL, "Hierarchy Mode", GetHierarchyMode, SetHierarchyMode, bool, false, AM_FILE);
-    ACCESSOR_ATTRIBUTE(ListView, VAR_INT, "Base Indent", GetBaseIndent, SetBaseIndent, int, 0, AM_FILE);
-    ACCESSOR_ATTRIBUTE(ListView, VAR_BOOL, "Clear Sel. On Defocus", GetClearSelectionOnDefocus, SetClearSelectionOnDefocus, bool, false, AM_FILE);
-    ACCESSOR_ATTRIBUTE(ListView, VAR_BOOL, "Select On Click End", GetSelectOnClickEnd, SetSelectOnClickEnd, bool, false, AM_FILE);
+    HierarchyContainer::RegisterObject(context);
+
+    COPY_BASE_ATTRIBUTES(ScrollView);
+    ENUM_ACCESSOR_ATTRIBUTE("Highlight Mode", GetHighlightMode, SetHighlightMode, HighlightMode, highlightModes, HM_FOCUS, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Multiselect", GetMultiselect, SetMultiselect, bool, false, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Hierarchy Mode", GetHierarchyMode, SetHierarchyMode, bool, false, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Base Indent", GetBaseIndent, SetBaseIndent, int, 0, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Clear Sel. On Defocus", GetClearSelectionOnDefocus, SetClearSelectionOnDefocus, bool, false, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Select On Click End", GetSelectOnClickEnd, SetSelectOnClickEnd, bool, false, AM_FILE);
 }
 
 void ListView::OnKey(int key, int buttons, int qualifiers)

+ 3 - 3
Source/Engine/UI/Menu.cpp

@@ -65,9 +65,9 @@ void Menu::RegisterObject(Context* context)
 {
     context->RegisterFactory<Menu>(UI_CATEGORY);
 
-    COPY_BASE_ATTRIBUTES(Menu, Button);
-    UPDATE_ATTRIBUTE_DEFAULT_VALUE(Menu, "Focus Mode", FM_NOTFOCUSABLE);
-    REF_ACCESSOR_ATTRIBUTE(Menu, VAR_INTVECTOR2, "Popup Offset", GetPopupOffset, SetPopupOffset, IntVector2, IntVector2::ZERO, AM_FILE);
+    COPY_BASE_ATTRIBUTES(Button);
+    UPDATE_ATTRIBUTE_DEFAULT_VALUE("Focus Mode", FM_NOTFOCUSABLE);
+    ACCESSOR_ATTRIBUTE("Popup Offset", GetPopupOffset, SetPopupOffset, IntVector2, IntVector2::ZERO, AM_FILE);
 }
 
 void Menu::Update(float timeStep)

+ 11 - 11
Source/Engine/UI/ScrollBar.cpp

@@ -78,17 +78,17 @@ void ScrollBar::RegisterObject(Context* context)
 {
     context->RegisterFactory<ScrollBar>(UI_CATEGORY);
 
-    COPY_BASE_ATTRIBUTES(ScrollBar, UIElement);
-    UPDATE_ATTRIBUTE_DEFAULT_VALUE(ScrollBar, "Is Enabled", true);
-    ENUM_ACCESSOR_ATTRIBUTE(ScrollBar, "Orientation", GetOrientation, SetOrientation, Orientation, orientations, O_HORIZONTAL, AM_FILE);
-    ACCESSOR_ATTRIBUTE(ScrollBar, VAR_FLOAT, "Range", GetRange, SetRange, float, 1.0f, AM_FILE);
-    ACCESSOR_ATTRIBUTE(ScrollBar, VAR_FLOAT, "Value", GetValue, SetValue, float, 0.0f, AM_FILE);
-    ACCESSOR_ATTRIBUTE(ScrollBar, VAR_FLOAT, "Scroll Step", GetScrollStep, SetScrollStep, float, DEFAULT_SCROLL_STEP, AM_FILE);
-    ACCESSOR_ATTRIBUTE(ScrollBar, VAR_FLOAT, "Step Factor", GetStepFactor, SetStepFactor, float, 1.0f, AM_FILE);
-    ATTRIBUTE(ScrollBar, VAR_INTRECT, "Left Image Rect", leftRect_, IntRect::ZERO, AM_FILE);
-    ATTRIBUTE(ScrollBar, VAR_INTRECT, "Right Image Rect", rightRect_, IntRect::ZERO, AM_FILE);
-    ATTRIBUTE(ScrollBar, VAR_INTRECT, "Up Image Rect", upRect_, IntRect::ZERO, AM_FILE);
-    ATTRIBUTE(ScrollBar, VAR_INTRECT, "Down Image Rect", downRect_, IntRect::ZERO, AM_FILE);
+    COPY_BASE_ATTRIBUTES(UIElement);
+    UPDATE_ATTRIBUTE_DEFAULT_VALUE("Is Enabled", true);
+    ENUM_ACCESSOR_ATTRIBUTE("Orientation", GetOrientation, SetOrientation, Orientation, orientations, O_HORIZONTAL, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Range", GetRange, SetRange, float, 1.0f, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Value", GetValue, SetValue, float, 0.0f, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Scroll Step", GetScrollStep, SetScrollStep, float, DEFAULT_SCROLL_STEP, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Step Factor", GetStepFactor, SetStepFactor, float, 1.0f, AM_FILE);
+    ATTRIBUTE("Left Image Rect", IntRect, leftRect_, IntRect::ZERO, AM_FILE);
+    ATTRIBUTE("Right Image Rect", IntRect, rightRect_, IntRect::ZERO, AM_FILE);
+    ATTRIBUTE("Up Image Rect", IntRect, upRect_, IntRect::ZERO, AM_FILE);
+    ATTRIBUTE("Down Image Rect", IntRect, downRect_, IntRect::ZERO, AM_FILE);
 }
 
 void ScrollBar::ApplyAttributes()

+ 12 - 12
Source/Engine/UI/ScrollView.cpp

@@ -94,18 +94,18 @@ void ScrollView::RegisterObject(Context* context)
 {
     context->RegisterFactory<ScrollView>(UI_CATEGORY);
 
-    COPY_BASE_ATTRIBUTES(ScrollView, UIElement);
-    UPDATE_ATTRIBUTE_DEFAULT_VALUE(ScrollView, "Clip Children", true);
-    UPDATE_ATTRIBUTE_DEFAULT_VALUE(ScrollView, "Is Enabled", true);
-    UPDATE_ATTRIBUTE_DEFAULT_VALUE(ScrollView, "Focus Mode", FM_FOCUSABLE_DEFOCUSABLE);
-    REF_ACCESSOR_ATTRIBUTE(ScrollView, VAR_INTVECTOR2, "View Position", GetViewPosition, SetViewPositionAttr, IntVector2, IntVector2::ZERO, AM_FILE);
-    ACCESSOR_ATTRIBUTE(ScrollView, VAR_FLOAT, "Scroll Step", GetScrollStep, SetScrollStep, float, 0.1f, AM_FILE);
-    ACCESSOR_ATTRIBUTE(ScrollView, VAR_FLOAT, "Page Step", GetPageStep, SetPageStep, float, 1.0f, AM_FILE);
-    ACCESSOR_ATTRIBUTE(ScrollView, VAR_BOOL, "Auto Show/Hide Scrollbars", GetScrollBarsAutoVisible, SetScrollBarsAutoVisible, bool, true, AM_FILE);
-    ACCESSOR_ATTRIBUTE(ScrollView, VAR_FLOAT, "Scroll Deceleration", GetScrollDeceleration, SetScrollDeceleration, float, 30.0f, AM_FILE);
-    ACCESSOR_ATTRIBUTE(ScrollView, VAR_FLOAT, "Scroll Snap Epsilon", GetScrollSnapEpsilon, SetScrollSnapEpsilon, float, 1.0f, AM_FILE);
-    ACCESSOR_ATTRIBUTE(ScrollView, VAR_BOOL, "Auto Disable Children", GetAutoDisableChildren, SetAutoDisableChildren, bool, false, AM_FILE);
-    ACCESSOR_ATTRIBUTE(ScrollView, VAR_FLOAT, "Auto Disable Threshold", GetAutoDisableThreshold, SetAutoDisableThreshold, float, 25.0f, AM_FILE);
+    COPY_BASE_ATTRIBUTES(UIElement);
+    UPDATE_ATTRIBUTE_DEFAULT_VALUE("Clip Children", true);
+    UPDATE_ATTRIBUTE_DEFAULT_VALUE("Is Enabled", true);
+    UPDATE_ATTRIBUTE_DEFAULT_VALUE("Focus Mode", FM_FOCUSABLE_DEFOCUSABLE);
+    ACCESSOR_ATTRIBUTE("View Position", GetViewPosition, SetViewPositionAttr, IntVector2, IntVector2::ZERO, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Scroll Step", GetScrollStep, SetScrollStep, float, 0.1f, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Page Step", GetPageStep, SetPageStep, float, 1.0f, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Auto Show/Hide Scrollbars", GetScrollBarsAutoVisible, SetScrollBarsAutoVisible, bool, true, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Scroll Deceleration", GetScrollDeceleration, SetScrollDeceleration, float, 30.0f, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Scroll Snap Epsilon", GetScrollSnapEpsilon, SetScrollSnapEpsilon, float, 1.0f, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Auto Disable Children", GetAutoDisableChildren, SetAutoDisableChildren, bool, false, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Auto Disable Threshold", GetAutoDisableThreshold, SetAutoDisableThreshold, float, 25.0f, AM_FILE);
 }
 
 void ScrollView::Update(float timeStep)

+ 6 - 11
Source/Engine/UI/Slider.cpp

@@ -39,11 +39,6 @@ const char* orientations[] =
     0
 };
 
-template<> Orientation Variant::Get<Orientation>() const
-{
-    return (Orientation)GetInt();
-}
-
 extern const char* UI_CATEGORY;
 
 Slider::Slider(Context* context) :
@@ -69,12 +64,12 @@ void Slider::RegisterObject(Context* context)
 {
     context->RegisterFactory<Slider>(UI_CATEGORY);
 
-    COPY_BASE_ATTRIBUTES(Slider, BorderImage);
-    UPDATE_ATTRIBUTE_DEFAULT_VALUE(Slider, "Is Enabled", true);
-    ENUM_ACCESSOR_ATTRIBUTE(Slider, "Orientation", GetOrientation, SetOrientation, Orientation, orientations, O_HORIZONTAL, AM_FILE);
-    ACCESSOR_ATTRIBUTE(Slider, VAR_FLOAT, "Range", GetRange, SetRange, float, 1.0f, AM_FILE);
-    ACCESSOR_ATTRIBUTE(Slider, VAR_FLOAT, "Value", GetValue, SetValue, float, 0.0f, AM_FILE);
-    ACCESSOR_ATTRIBUTE(Slider, VAR_FLOAT, "Repeat Rate", GetRepeatRate, SetRepeatRate, float, 0.0f, AM_FILE);
+    COPY_BASE_ATTRIBUTES(BorderImage);
+    UPDATE_ATTRIBUTE_DEFAULT_VALUE("Is Enabled", true);
+    ENUM_ACCESSOR_ATTRIBUTE("Orientation", GetOrientation, SetOrientation, Orientation, orientations, O_HORIZONTAL, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Range", GetRange, SetRange, float, 1.0f, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Value", GetValue, SetValue, float, 0.0f, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Repeat Rate", GetRepeatRate, SetRepeatRate, float, 0.0f, AM_FILE);
 }
 
 void Slider::Update(float timeStep)

+ 39 - 39
Source/Engine/UI/Sprite.cpp

@@ -54,28 +54,28 @@ Sprite::~Sprite()
 void Sprite::RegisterObject(Context* context)
 {
     context->RegisterFactory<Sprite>(UI_CATEGORY);
-    
-    REF_ACCESSOR_ATTRIBUTE(Sprite, VAR_STRING, "Name", GetName, SetName, String, String::EMPTY, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(Sprite, VAR_VECTOR2, "Position", GetPosition, SetPosition, Vector2, Vector2::ZERO, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(Sprite, VAR_INTVECTOR2, "Size", GetSize, SetSize, IntVector2, IntVector2::ZERO, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(Sprite, VAR_INTVECTOR2, "Hotspot", GetHotSpot, SetHotSpot, IntVector2, IntVector2::ZERO, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(Sprite, VAR_VECTOR2, "Scale", GetScale, SetScale, Vector2, Vector2::ONE, AM_FILE);
-    ACCESSOR_ATTRIBUTE(Sprite, VAR_FLOAT, "Rotation", GetRotation, SetRotation, float, 0.0f, AM_FILE);
-    ACCESSOR_ATTRIBUTE(Sprite, VAR_RESOURCEREF, "Texture", GetTextureAttr, SetTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(Sprite, VAR_INTRECT, "Image Rect", GetImageRect, SetImageRect, IntRect, IntRect::ZERO, AM_FILE);
-    ENUM_ACCESSOR_ATTRIBUTE(Sprite, "Blend Mode", GetBlendMode, SetBlendMode, BlendMode, blendModeNames, 0, AM_FILE);
-    ENUM_ACCESSOR_ATTRIBUTE(Sprite, "Horiz Alignment", GetHorizontalAlignment, SetHorizontalAlignment, HorizontalAlignment, horizontalAlignments, HA_LEFT, AM_FILE);
-    ENUM_ACCESSOR_ATTRIBUTE(Sprite, "Vert Alignment", GetVerticalAlignment, SetVerticalAlignment, VerticalAlignment, verticalAlignments, VA_TOP, AM_FILE);
-    ACCESSOR_ATTRIBUTE(Sprite, VAR_INT, "Priority", GetPriority, SetPriority, int, 0, AM_FILE);
-    ACCESSOR_ATTRIBUTE(Sprite, VAR_FLOAT, "Opacity", GetOpacity, SetOpacity, float, 1.0f, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(Sprite, VAR_COLOR, "Color", GetColorAttr, SetColor, Color, Color::WHITE, AM_FILE);
-    ATTRIBUTE(Sprite, VAR_COLOR, "Top Left Color", color_[0], Color::WHITE, AM_FILE);
-    ATTRIBUTE(Sprite, VAR_COLOR, "Top Right Color", color_[1], Color::WHITE, AM_FILE);
-    ATTRIBUTE(Sprite, VAR_COLOR, "Bottom Left Color", color_[2], Color::WHITE, AM_FILE);
-    ATTRIBUTE(Sprite, VAR_COLOR, "Bottom Right Color", color_[3], Color::WHITE, AM_FILE);
-    ACCESSOR_ATTRIBUTE(Sprite, VAR_BOOL, "Is Visible", IsVisible, SetVisible, bool, true, AM_FILE);
-    ACCESSOR_ATTRIBUTE(Sprite, VAR_BOOL, "Use Derived Opacity", GetUseDerivedOpacity, SetUseDerivedOpacity, bool, true, AM_FILE);
-    ATTRIBUTE(Sprite, VAR_VARIANTMAP, "Variables", vars_, Variant::emptyVariantMap, AM_FILE);
+
+    ACCESSOR_ATTRIBUTE("Name", GetName, SetName, String, String::EMPTY, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Position", GetPosition, SetPosition, Vector2, Vector2::ZERO, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Size", GetSize, SetSize, IntVector2, IntVector2::ZERO, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Hotspot", GetHotSpot, SetHotSpot, IntVector2, IntVector2::ZERO, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Scale", GetScale, SetScale, Vector2, Vector2::ONE, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Rotation", GetRotation, SetRotation, float, 0.0f, AM_FILE);
+    MIXED_ACCESSOR_ATTRIBUTE("Texture", GetTextureAttr, SetTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_FILE);
+    ACCESSOR_ATTRIBUTE("Image Rect", GetImageRect, SetImageRect, IntRect, IntRect::ZERO, AM_FILE);
+    ENUM_ACCESSOR_ATTRIBUTE("Blend Mode", GetBlendMode, SetBlendMode, BlendMode, blendModeNames, 0, AM_FILE);
+    ENUM_ACCESSOR_ATTRIBUTE("Horiz Alignment", GetHorizontalAlignment, SetHorizontalAlignment, HorizontalAlignment, horizontalAlignments, HA_LEFT, AM_FILE);
+    ENUM_ACCESSOR_ATTRIBUTE("Vert Alignment", GetVerticalAlignment, SetVerticalAlignment, VerticalAlignment, verticalAlignments, VA_TOP, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Priority", GetPriority, SetPriority, int, 0, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Opacity", GetOpacity, SetOpacity, float, 1.0f, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Color", GetColorAttr, SetColor, Color, Color::WHITE, AM_FILE);
+    ATTRIBUTE("Top Left Color", Color, color_[0], Color::WHITE, AM_FILE);
+    ATTRIBUTE("Top Right Color", Color, color_[1], Color::WHITE, AM_FILE);
+    ATTRIBUTE("Bottom Left Color", Color, color_[2], Color::WHITE, AM_FILE);
+    ATTRIBUTE("Bottom Right Color", Color, color_[3], Color::WHITE, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Is Visible", IsVisible, SetVisible, bool, true, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Use Derived Opacity", GetUseDerivedOpacity, SetUseDerivedOpacity, bool, true, AM_FILE);
+    ATTRIBUTE("Variables", VariantMap, vars_, Variant::emptyVariantMap, AM_FILE);
 }
 
 bool Sprite::IsWithinScissor(const IntRect& currentScissor)
@@ -97,15 +97,15 @@ void Sprite::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexDat
     if (GetDerivedOpacity() < 1.0f || color_[C_TOPLEFT].a_ < 1.0f || color_[C_TOPRIGHT].a_ < 1.0f ||
         color_[C_BOTTOMLEFT].a_ < 1.0f || color_[C_BOTTOMRIGHT].a_ < 1.0f)
         allOpaque = false;
-    
+
     const IntVector2& size = GetSize();
     UIBatch batch(this, blendMode_ == BLEND_REPLACE && !allOpaque ? BLEND_ALPHA : blendMode_, currentScissor, texture_, &vertexData);
-    
+
     batch.AddQuad(GetTransform(), 0, 0, size.x_, size.y_, imageRect_.left_, imageRect_.top_, imageRect_.right_ -
         imageRect_.left_, imageRect_.bottom_ - imageRect_.top_);
-    
+
     UIBatch::AddOrMerge(batch, batches);
-    
+
     // Reset hovering for next frame
     hovering_ = false;
 }
@@ -203,9 +203,9 @@ const Matrix3x4& Sprite::GetTransform() const
     if (positionDirty_)
     {
         Vector2 pos = floatPosition_;
-        
+
         Matrix3x4 parentTransform;
-        
+
         if (parent_)
         {
             Sprite* parentSprite = dynamic_cast<Sprite*>(parent_);
@@ -217,16 +217,16 @@ const Matrix3x4& Sprite::GetTransform() const
                 parentTransform = Matrix3x4::IDENTITY;
                 parentTransform.SetTranslation(Vector3((float)parentScreenPos.x_, (float)parentScreenPos.y_, 0.0f));
             }
-            
+
             switch (GetHorizontalAlignment())
             {
             case HA_LEFT:
                 break;
-                
+
             case HA_CENTER:
                 pos.x_ += (float)(parent_->GetSize().x_ / 2);
                 break;
-                
+
             case HA_RIGHT:
                 pos.x_ += (float)parent_->GetSize().x_;
                 break;
@@ -235,11 +235,11 @@ const Matrix3x4& Sprite::GetTransform() const
             {
             case VA_TOP:
                 break;
-                
+
             case VA_CENTER:
                 pos.y_ += (float)(parent_->GetSize().y_ / 2);
                 break;
-                
+
             case VA_BOTTOM:
                 pos.y_ += (float)(parent_->GetSize().y_);
                 break;
@@ -247,24 +247,24 @@ const Matrix3x4& Sprite::GetTransform() const
         }
         else
             parentTransform = Matrix3x4::IDENTITY;
-        
+
         Matrix3x4 hotspotAdjust(Matrix3x4::IDENTITY);
         hotspotAdjust.SetTranslation(Vector3((float)-hotSpot_.x_, (float)-hotSpot_.y_, 0.0f));
-        
+
         Matrix3x4 mainTransform(Vector3(pos, 0.0f), Quaternion(rotation_, Vector3::FORWARD), Vector3(scale_, 1.0f));
-        
+
         transform_ = parentTransform * mainTransform * hotspotAdjust;
         positionDirty_ = false;
-        
+
         // Calculate an approximate screen position for GetElementAt(), or pixel-perfect child elements
         Vector3 topLeftCorner = transform_ * Vector3::ZERO;
         screenPosition_ = IntVector2((int)topLeftCorner.x_, (int)topLeftCorner.y_);
     }
-    
+
     return transform_;
 }
 
-void Sprite::SetTextureAttr(ResourceRef value)
+void Sprite::SetTextureAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SetTexture(cache->GetResource<Texture2D>(value.name_));

+ 7 - 7
Source/Engine/UI/Sprite.h

@@ -32,7 +32,7 @@ namespace Urho3D
 class URHO3D_API Sprite : public UIElement
 {
     OBJECT(Sprite);
-    
+
 public:
     /// Construct.
     Sprite(Context* context);
@@ -40,7 +40,7 @@ public:
     virtual ~Sprite();
     /// Register object factory.
     static void RegisterObject(Context* context);
-    
+
     /// Return whether is visible and inside a scissor rectangle and should be rendered.
     virtual bool IsWithinScissor(const IntRect& currentScissor);
     /// Update and return screen position.
@@ -49,7 +49,7 @@ public:
     virtual void GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor);
     /// React to position change.
     virtual void OnPositionSet();
-    
+
     /// Set floating point position.
     void SetPosition(const Vector2& position);
     /// Set floating point position.
@@ -74,7 +74,7 @@ public:
     void SetFullImageRect();
     /// Set blend mode.
     void SetBlendMode(BlendMode mode);
-    
+
     /// Return floating point position.
     const Vector2& GetPosition() const { return floatPosition_; }
     /// Return hotspot.
@@ -89,14 +89,14 @@ public:
     const IntRect& GetImageRect() const { return imageRect_; }
     /// Return blend mode.
     BlendMode GetBlendMode() const { return blendMode_; }
-    
+
     /// Set texture attribute.
-    void SetTextureAttr(ResourceRef value);
+    void SetTextureAttr(const ResourceRef& value);
     /// Return texture attribute.
     ResourceRef GetTextureAttr() const;
     /// Update and return rendering transform, also used to transform child sprites.
     const Matrix3x4& GetTransform() const;
-    
+
 protected:
     /// Floating point position.
     Vector2 floatPosition_;

+ 32 - 32
Source/Engine/UI/Text.cpp

@@ -77,18 +77,18 @@ void Text::RegisterObject(Context* context)
 {
     context->RegisterFactory<Text>(UI_CATEGORY);
 
-    COPY_BASE_ATTRIBUTES(Text, UIElement);
-    UPDATE_ATTRIBUTE_DEFAULT_VALUE(Text, "Use Derived Opacity", false);
-    ACCESSOR_ATTRIBUTE(Text, VAR_RESOURCEREF, "Font", GetFontAttr, SetFontAttr, ResourceRef, ResourceRef(Font::GetTypeStatic()), AM_FILE);
-    ATTRIBUTE(Text, VAR_INT, "Font Size", fontSize_, DEFAULT_FONT_SIZE, AM_FILE);
-    ATTRIBUTE(Text, VAR_STRING, "Text", text_, String::EMPTY, AM_FILE);
-    ENUM_ATTRIBUTE(Text, "Text Alignment", textAlignment_, horizontalAlignments, HA_LEFT, AM_FILE);
-    ATTRIBUTE(Text, VAR_FLOAT, "Row Spacing", rowSpacing_, 1.0f, AM_FILE);
-    ATTRIBUTE(Text, VAR_BOOL, "Word Wrap", wordWrap_, false, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(Text, VAR_COLOR, "Selection Color", GetSelectionColor, SetSelectionColor, Color, Color::TRANSPARENT, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(Text, VAR_COLOR, "Hover Color", GetHoverColor, SetHoverColor, Color, Color::TRANSPARENT, AM_FILE);
-    ENUM_ATTRIBUTE(Text, "Text Effect", textEffect_, textEffects, TE_NONE, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(Text, VAR_COLOR, "Effect Color", GetEffectColor, SetEffectColor, Color, Color::BLACK, AM_FILE);
+    COPY_BASE_ATTRIBUTES(UIElement);
+    UPDATE_ATTRIBUTE_DEFAULT_VALUE("Use Derived Opacity", false);
+    MIXED_ACCESSOR_ATTRIBUTE("Font", GetFontAttr, SetFontAttr, ResourceRef, ResourceRef(Font::GetTypeStatic()), AM_FILE);
+    ATTRIBUTE("Font Size", int, fontSize_, DEFAULT_FONT_SIZE, AM_FILE);
+    ATTRIBUTE("Text", String, text_, String::EMPTY, AM_FILE);
+    ENUM_ATTRIBUTE("Text Alignment", textAlignment_, horizontalAlignments, HA_LEFT, AM_FILE);
+    ATTRIBUTE("Row Spacing", float, rowSpacing_, 1.0f, AM_FILE);
+    ATTRIBUTE("Word Wrap", bool, wordWrap_, false, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Selection Color", GetSelectionColor, SetSelectionColor, Color, Color::TRANSPARENT, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Hover Color", GetHoverColor, SetHoverColor, Color, Color::TRANSPARENT, AM_FILE);
+    ENUM_ATTRIBUTE("Text Effect", textEffect_, textEffects, TE_NONE, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Effect Color", GetEffectColor, SetEffectColor, Color, Color::BLACK, AM_FILE);
 
     // Change the default value for UseDerivedOpacity
     context->GetAttribute<Text>("Use Derived Opacity")->defaultValue_ = false;
@@ -116,7 +116,7 @@ void Text::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData,
         hovering_ = false;
         return;
     }
-    
+
     // If face has changed or char locations are not valid anymore, update before rendering
     if (charLocationsDirty_ || !fontFace_ || face != fontFace_)
         UpdateCharLocations();
@@ -126,13 +126,13 @@ void Text::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData,
         for (unsigned i = 0; i < printText_.Size(); ++i)
             face->GetGlyph(printText_[i]);
     }
-    
+
     // Hovering and/or whole selection batch
     if ((hovering_ && hoverColor_.a_ > 0.0) || (selected_ && selectionColor_.a_ > 0.0f))
     {
         bool both = hovering_ && selected_ && hoverColor_.a_ > 0.0 && selectionColor_.a_ > 0.0f;
         UIBatch batch(this, BLEND_ALPHA, currentScissor, 0, &vertexData);
-        batch.SetColor(both ? selectionColor_.Lerp(hoverColor_, 0.5f) : (selected_ && selectionColor_.a_ > 0.0f ? 
+        batch.SetColor(both ? selectionColor_.Lerp(hoverColor_, 0.5f) : (selected_ && selectionColor_.a_ > 0.0f ?
             selectionColor_: hoverColor_));
         batch.AddQuad(0, 0, GetWidth(), GetHeight(), 0, 0);
         UIBatch::AddOrMerge(batch, batches);
@@ -189,12 +189,12 @@ void Text::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData,
         case TE_NONE:
             ConstructBatch(pageBatch, pageGlyphLocation, 0, 0);
             break;
-            
+
         case TE_SHADOW:
             ConstructBatch(pageBatch, pageGlyphLocation, 1, 1, &effectColor_, effectDepthBias_);
             ConstructBatch(pageBatch, pageGlyphLocation, 0, 0);
             break;
-            
+
         case TE_STROKE:
             ConstructBatch(pageBatch, pageGlyphLocation, -1, -1, &effectColor_, effectDepthBias_);
             ConstructBatch(pageBatch, pageGlyphLocation, 0, -1, &effectColor_, effectDepthBias_);
@@ -364,7 +364,7 @@ IntVector2 Text::GetCharSize(unsigned index)
     return charLocations_[index].size_;
 }
 
-void Text::SetFontAttr(ResourceRef value)
+void Text::SetFontAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     font_ = cache->GetResource<Font>(value.name_);
@@ -397,7 +397,7 @@ void Text::UpdateText(bool onResize)
 {
     rowWidths_.Clear();
     printText_.Clear();
-    
+
     if (font_)
     {
         FontFace* face = font_->GetFace(fontSize_);
@@ -405,7 +405,7 @@ void Text::UpdateText(bool onResize)
             return;
 
         rowHeight_ = face->GetRowHeight();
-        
+
         int width = 0;
         int height = 0;
         int rowWidth = 0;
@@ -425,7 +425,7 @@ void Text::UpdateText(bool onResize)
             unsigned nextBreak = 0;
             unsigned lineStart = 0;
             printToText_.Clear();
-            
+
             for (unsigned i = 0; i < unicodeText_.Size(); ++i)
             {
                 unsigned j;
@@ -561,7 +561,7 @@ void Text::UpdateText(bool onResize)
             SetWidth(width);
         }
         SetFixedHeight(height);
-        
+
         charLocationsDirty_ = true;
     }
     else
@@ -569,8 +569,8 @@ void Text::UpdateText(bool onResize)
         // No font, nothing to render
         pageGlyphLocations_.Clear();
     }
-    
-    // If wordwrap is on, parent may need layout update to correct for overshoot in size. However, do not do this when the 
+
+    // If wordwrap is on, parent may need layout update to correct for overshoot in size. However, do not do this when the
     // update is a response to resize, as that could cause infinite recursion
     if (wordWrap_ && !onResize)
     {
@@ -587,9 +587,9 @@ void Text::UpdateCharLocations()
     if (!face)
         return;
     fontFace_ = face;
-    
+
     int rowHeight = (int)(rowSpacing_ * rowHeight_);
-    
+
     // Store position & size of each character, and locations per texture page
     unsigned numChars = unicodeText_.Size();
     charLocations_.Resize(numChars + 1);
@@ -598,17 +598,17 @@ void Text::UpdateCharLocations()
         pageGlyphLocations_[i].Clear();
 
     IntVector2 offset = font_->GetTotalGlyphOffset(fontSize_);
-    
+
     unsigned rowIndex = 0;
     unsigned lastFilled = 0;
     int x = GetRowStartPosition(rowIndex) + offset.x_;
     int y = offset.y_;
-    
+
     for (unsigned i = 0; i < printText_.Size(); ++i)
     {
         CharLocation loc;
         loc.position_ = IntVector2(x, y);
-        
+
         unsigned c = printText_[i];
         if (c != '\n')
         {
@@ -630,7 +630,7 @@ void Text::UpdateCharLocations()
             x = GetRowStartPosition(++rowIndex);
             y += rowHeight;
         }
-        
+
         // Fill gaps in case characters were skipped from printing
         for (unsigned j = lastFilled; j <= printToText_[i]; ++j)
             charLocations_[j] = loc;
@@ -639,7 +639,7 @@ void Text::UpdateCharLocations()
     // Store the ending position
     charLocations_[numChars].position_ = IntVector2(x, y);
     charLocations_[numChars].size_ = IntVector2::ZERO;
-    
+
     charLocationsDirty_ = false;
 }
 
@@ -689,7 +689,7 @@ void Text::ConstructBatch(UIBatch& pageBatch, const PODVector<GlyphLocation>& pa
     float depthBias)
 {
     unsigned startDataSize = pageBatch.vertexData_->Size();
-    
+
     if (!color)
         pageBatch.SetDefaultColor();
     else

+ 1 - 1
Source/Engine/UI/Text.h

@@ -162,7 +162,7 @@ public:
     /// Return effect Z bias.
     float GetEffectDepthBias() const { return effectDepthBias_; }
     /// Set font attribute.
-    void SetFontAttr(ResourceRef value);
+    void SetFontAttr(const ResourceRef& value);
     /// Return font attribute.
     ResourceRef GetFontAttr() const;
 

+ 65 - 65
Source/Engine/UI/Text3D.cpp

@@ -66,30 +66,30 @@ Text3D::~Text3D()
 void Text3D::RegisterObject(Context* context)
 {
     context->RegisterFactory<Text3D>(GEOMETRY_CATEGORY);
-    
-    ACCESSOR_ATTRIBUTE(Text3D, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Text3D, VAR_RESOURCEREF, "Font", GetFontAttr, SetFontAttr, ResourceRef, ResourceRef(Font::GetTypeStatic()), AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Text3D, VAR_RESOURCEREF, "Material", GetMaterialAttr, SetMaterialAttr, ResourceRef, ResourceRef(Material::GetTypeStatic()), AM_DEFAULT);
-    ATTRIBUTE(Text3D, VAR_INT, "Font Size", text_.fontSize_, DEFAULT_FONT_SIZE, AM_DEFAULT);
-    ATTRIBUTE(Text3D, VAR_STRING, "Text", text_.text_, String::EMPTY, AM_DEFAULT);
-    ENUM_ATTRIBUTE(Text3D, "Text Alignment", text_.textAlignment_, horizontalAlignments, HA_LEFT, AM_DEFAULT);
-    ATTRIBUTE(Text3D, VAR_FLOAT, "Row Spacing", text_.rowSpacing_, 1.0f, AM_DEFAULT);
-    ATTRIBUTE(Text3D, VAR_BOOL, "Word Wrap", text_.wordWrap_, false, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Text3D, VAR_BOOL, "Can Be Occluded", IsOccludee, SetOccludee, bool, true, AM_DEFAULT);
-    ENUM_ATTRIBUTE(Text3D, "Face Camera Mode", faceCameraMode_, faceCameraModeNames, FC_NONE, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Text3D, VAR_FLOAT, "Draw Distance", GetDrawDistance, SetDrawDistance, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Text3D, VAR_INT, "Width", GetWidth, SetWidth, int, 0, AM_DEFAULT);
-    ENUM_ACCESSOR_ATTRIBUTE(Text3D, "Horiz Alignment", GetHorizontalAlignment, SetHorizontalAlignment, HorizontalAlignment, horizontalAlignments, HA_LEFT, AM_DEFAULT);
-    ENUM_ACCESSOR_ATTRIBUTE(Text3D, "Vert Alignment", GetVerticalAlignment, SetVerticalAlignment, VerticalAlignment, verticalAlignments, VA_TOP, AM_DEFAULT);
-    REF_ACCESSOR_ATTRIBUTE(Text3D, VAR_COLOR, "Color", GetColorAttr, SetColor, Color, Color::WHITE, AM_DEFAULT);
-    ATTRIBUTE(Text3D, VAR_COLOR, "Top Left Color", text_.color_[0], Color::WHITE, AM_DEFAULT);
-    ATTRIBUTE(Text3D, VAR_COLOR, "Top Right Color", text_.color_[1], Color::WHITE, AM_DEFAULT);
-    ATTRIBUTE(Text3D, VAR_COLOR, "Bottom Left Color", text_.color_[2], Color::WHITE, AM_DEFAULT);
-    ATTRIBUTE(Text3D, VAR_COLOR, "Bottom Right Color", text_.color_[3], Color::WHITE, AM_DEFAULT);
-    ENUM_ATTRIBUTE(Text3D, "Text Effect", text_.textEffect_, textEffects, TE_NONE, AM_DEFAULT);
-    REF_ACCESSOR_ATTRIBUTE(Text3D, VAR_COLOR, "Effect Color", GetEffectColor, SetEffectColor, Color, Color::BLACK, AM_DEFAULT);
-    ATTRIBUTE(Text3D, VAR_FLOAT, "Effect Depth Bias", text_.effectDepthBias_, DEFAULT_EFFECT_DEPTH_BIAS, AM_DEFAULT);
-    COPY_BASE_ATTRIBUTES(Text3D, Drawable);
+
+    ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Font", GetFontAttr, SetFontAttr, ResourceRef, ResourceRef(Font::GetTypeStatic()), AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Material", GetMaterialAttr, SetMaterialAttr, ResourceRef, ResourceRef(Material::GetTypeStatic()), AM_DEFAULT);
+    ATTRIBUTE("Font Size", int, text_.fontSize_, DEFAULT_FONT_SIZE, AM_DEFAULT);
+    ATTRIBUTE("Text", String, text_.text_, String::EMPTY, AM_DEFAULT);
+    ENUM_ATTRIBUTE("Text Alignment", text_.textAlignment_, horizontalAlignments, HA_LEFT, AM_DEFAULT);
+    ATTRIBUTE("Row Spacing", float, text_.rowSpacing_, 1.0f, AM_DEFAULT);
+    ATTRIBUTE("Word Wrap", bool, text_.wordWrap_, false, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Can Be Occluded", IsOccludee, SetOccludee, bool, true, AM_DEFAULT);
+    ENUM_ATTRIBUTE("Face Camera Mode", faceCameraMode_, faceCameraModeNames, FC_NONE, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Draw Distance", GetDrawDistance, SetDrawDistance, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Width", GetWidth, SetWidth, int, 0, AM_DEFAULT);
+    ENUM_ACCESSOR_ATTRIBUTE("Horiz Alignment", GetHorizontalAlignment, SetHorizontalAlignment, HorizontalAlignment, horizontalAlignments, HA_LEFT, AM_DEFAULT);
+    ENUM_ACCESSOR_ATTRIBUTE("Vert Alignment", GetVerticalAlignment, SetVerticalAlignment, VerticalAlignment, verticalAlignments, VA_TOP, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Color", GetColorAttr, SetColor, Color, Color::WHITE, AM_DEFAULT);
+    ATTRIBUTE("Top Left Color", Color, text_.color_[0], Color::WHITE, AM_DEFAULT);
+    ATTRIBUTE("Top Right Color", Color, text_.color_[1], Color::WHITE, AM_DEFAULT);
+    ATTRIBUTE("Bottom Left Color", Color, text_.color_[2], Color::WHITE, AM_DEFAULT);
+    ATTRIBUTE("Bottom Right Color", Color, text_.color_[3], Color::WHITE, AM_DEFAULT);
+    ENUM_ATTRIBUTE("Text Effect", text_.textEffect_, textEffects, TE_NONE, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Effect Color", GetEffectColor, SetEffectColor, Color, Color::BLACK, AM_DEFAULT);
+    ATTRIBUTE("Effect Depth Bias", float, text_.effectDepthBias_, DEFAULT_EFFECT_DEPTH_BIAS, AM_DEFAULT);
+    COPY_BASE_ATTRIBUTES(Drawable);
 }
 
 void Text3D::ApplyAttributes()
@@ -103,7 +103,7 @@ void Text3D::ApplyAttributes()
 void Text3D::UpdateBatches(const FrameInfo& frame)
 {
     distance_ = frame.camera_->GetDistance(GetWorldBoundingBox().Center());
-    
+
     if (faceCameraMode_ != FC_NONE)
     {
         Vector3 worldPosition = node_->GetWorldPosition();
@@ -111,7 +111,7 @@ void Text3D::UpdateBatches(const FrameInfo& frame)
             worldPosition, node_->GetWorldRotation(), faceCameraMode_), node_->GetWorldScale());
         worldBoundingBoxDirty_ = true;
     }
-    
+
     for (unsigned i = 0; i < batches_.Size(); ++i)
     {
         batches_[i].distance_ = distance_;
@@ -130,7 +130,7 @@ void Text3D::UpdateGeometry(const FrameInfo& frame)
                 uiBatches_[i].vertexStart_) / UI_VERTEX_SIZE);
         }
     }
-    
+
     if ((geometryDirty_ || vertexBuffer_->IsDataLost()) && uiVertexData_.Size())
     {
         unsigned vertexCount = uiVertexData_.Size() / UI_VERTEX_SIZE;
@@ -138,7 +138,7 @@ void Text3D::UpdateGeometry(const FrameInfo& frame)
             vertexBuffer_->SetSize(vertexCount, MASK_POSITION | MASK_COLOR | MASK_TEXCOORD1);
         vertexBuffer_->SetData(&uiVertexData_[0]);
     }
-    
+
     geometryDirty_ = false;
 }
 
@@ -153,7 +153,7 @@ UpdateGeometryType Text3D::GetUpdateGeometryType()
 void Text3D::SetMaterial(Material* material)
 {
     material_ = material;
-    
+
     UpdateTextMaterials(true);
 }
 
@@ -166,7 +166,7 @@ bool Text3D::SetFont(const String& fontName, int size)
     MarkTextDirty();
     UpdateTextBatches();
     UpdateTextMaterials();
-    
+
     return success;
 }
 
@@ -177,14 +177,14 @@ bool Text3D::SetFont(Font* font, int size)
     MarkTextDirty();
     UpdateTextBatches();
     UpdateTextMaterials();
-    
+
     return success;
 }
 
 void Text3D::SetText(const String& text)
 {
     text_.SetText(text);
-    
+
     // Changing text requires materials to be re-evaluated, in case the font is multi-page
     MarkTextDirty();
     UpdateTextBatches();
@@ -194,49 +194,49 @@ void Text3D::SetText(const String& text)
 void Text3D::SetAlignment(HorizontalAlignment hAlign, VerticalAlignment vAlign)
 {
     text_.SetAlignment(hAlign, vAlign);
-    
+
     MarkTextDirty();
 }
 
 void Text3D::SetHorizontalAlignment(HorizontalAlignment align)
 {
     text_.SetHorizontalAlignment(align);
-    
+
     MarkTextDirty();
 }
 
 void Text3D::SetVerticalAlignment(VerticalAlignment align)
 {
     text_.SetVerticalAlignment(align);
-    
+
     MarkTextDirty();
 }
 
 void Text3D::SetTextAlignment(HorizontalAlignment align)
 {
     text_.SetTextAlignment(align);
-    
+
     MarkTextDirty();
 }
 
 void Text3D::SetRowSpacing(float spacing)
 {
     text_.SetRowSpacing(spacing);
-    
+
     MarkTextDirty();
 }
 
 void Text3D::SetWordwrap(bool enable)
 {
     text_.SetWordwrap(enable);
-    
+
     MarkTextDirty();
 }
 
 void Text3D::SetTextEffect(TextEffect textEffect)
 {
     text_.SetTextEffect(textEffect);
-    
+
     MarkTextDirty();
     UpdateTextMaterials(true);
 }
@@ -244,7 +244,7 @@ void Text3D::SetTextEffect(TextEffect textEffect)
 void Text3D::SetEffectColor(const Color& effectColor)
 {
     text_.SetEffectColor(effectColor);
-    
+
     MarkTextDirty();
     UpdateTextMaterials();
 }
@@ -252,7 +252,7 @@ void Text3D::SetEffectColor(const Color& effectColor)
 void Text3D::SetEffectDepthBias(float bias)
 {
     text_.SetEffectDepthBias(bias);
-    
+
     MarkTextDirty();
 }
 
@@ -260,28 +260,28 @@ void Text3D::SetWidth(int width)
 {
     text_.SetMinWidth(width);
     text_.SetWidth(width);
-    
+
     MarkTextDirty();
 }
 
 void Text3D::SetColor(const Color& color)
 {
     text_.SetColor(color);
-    
+
     MarkTextDirty();
 }
 
 void Text3D::SetColor(Corner corner, const Color& color)
 {
     text_.SetColor(corner, color);
-    
+
     MarkTextDirty();
 }
 
 void Text3D::SetOpacity(float opacity)
 {
     text_.SetOpacity(opacity);
-    
+
     MarkTextDirty();
 }
 
@@ -290,7 +290,7 @@ void Text3D::SetFaceCameraMode(FaceCameraMode mode)
     if (mode != faceCameraMode_)
     {
         faceCameraMode_ = mode;
-        
+
         // Bounding box must be recalculated
         OnMarkedDirty(node_);
     }
@@ -404,7 +404,7 @@ float Text3D::GetOpacity() const
 void Text3D::OnNodeSet(Node* node)
 {
     Drawable::OnNodeSet(node);
-    
+
     if (node)
         customWorldTransform_ = node->GetWorldTransform();
 }
@@ -413,7 +413,7 @@ void Text3D::OnWorldBoundingBoxUpdate()
 {
     if (textDirty_)
         UpdateTextBatches();
-    
+
     // In face camera mode, use the last camera rotation to build the world bounding box
     worldBoundingBox_ = boundingBox_.Transformed(faceCameraMode_ != FC_NONE ? Matrix3x4(node_->GetWorldPosition(),
         customWorldTransform_.Rotation(), node_->GetWorldScale()) : node_->GetWorldTransform());
@@ -422,18 +422,18 @@ void Text3D::OnWorldBoundingBoxUpdate()
 void Text3D::MarkTextDirty()
 {
     textDirty_ = true;
-    
+
     OnMarkedDirty(node_);
     MarkNetworkUpdate();
 }
 
-void Text3D::SetMaterialAttr(ResourceRef value)
+void Text3D::SetMaterialAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SetMaterial(cache->GetResource<Material>(value.name_));
 }
 
-void Text3D::SetFontAttr(ResourceRef value)
+void Text3D::SetFontAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     text_.font_ = cache->GetResource<Font>(value.name_);
@@ -453,42 +453,42 @@ void Text3D::UpdateTextBatches()
 {
     uiBatches_.Clear();
     uiVertexData_.Clear();
-    
+
     text_.GetBatches(uiBatches_, uiVertexData_, IntRect::ZERO);
-    
+
     Vector3 offset(Vector3::ZERO);
-    
+
     switch (text_.GetHorizontalAlignment())
     {
     case HA_LEFT:
         break;
-        
+
     case HA_CENTER:
         offset.x_ -= (float)text_.GetWidth() * 0.5f;
         break;
-        
+
     case HA_RIGHT:
         offset.x_ -= (float)text_.GetWidth();
         break;
     }
-    
+
     switch (text_.GetVerticalAlignment())
     {
     case VA_TOP:
         break;
-        
+
     case VA_CENTER:
         offset.y_ -= (float)text_.GetHeight() * 0.5f;
         break;
-        
+
     case VA_BOTTOM:
         offset.y_ -= (float)text_.GetHeight();
         break;
     }
-    
+
     boundingBox_.defined_ = false;
     boundingBox_.min_ = boundingBox_.max_ = Vector3::ZERO;
-    
+
     for (unsigned i = 0; i < uiVertexData_.Size(); i += UI_VERTEX_SIZE)
     {
         Vector3& position = *(reinterpret_cast<Vector3*>(&uiVertexData_[i]));
@@ -497,7 +497,7 @@ void Text3D::UpdateTextBatches()
         position.y_ = -position.y_;
         boundingBox_.Merge(position);
     }
-    
+
     textDirty_ = false;
     geometryDirty_ = true;
 }
@@ -506,7 +506,7 @@ void Text3D::UpdateTextMaterials(bool forceUpdate)
 {
     batches_.Resize(uiBatches_.Size());
     geometries_.Resize(uiBatches_.Size());
-    
+
     for (unsigned i = 0; i < batches_.Size(); ++i)
     {
         if (!geometries_[i])
@@ -515,7 +515,7 @@ void Text3D::UpdateTextMaterials(bool forceUpdate)
             geometry->SetVertexBuffer(0, vertexBuffer_, MASK_POSITION | MASK_COLOR | MASK_TEXCOORD1);
             batches_[i].geometry_ = geometries_[i] = geometry;
         }
-        
+
         if (!batches_[i].material_ || forceUpdate)
         {
             // If material not defined, create a reasonable default from scratch
@@ -554,7 +554,7 @@ void Text3D::UpdateTextMaterials(bool forceUpdate)
             else
                 batches_[i].material_ = material_->Clone();
         }
-        
+
         Material* material = batches_[i].material_;
         Texture* texture = uiBatches_[i].texture_;
         material->SetTexture(TU_DIFFUSE, texture);

+ 10 - 10
Source/Engine/UI/Text3D.h

@@ -36,7 +36,7 @@ class Text;
 class URHO3D_API Text3D : public Drawable
 {
     OBJECT(Text3D);
-    
+
 public:
     /// Construct.
     Text3D(Context* context);
@@ -44,7 +44,7 @@ public:
     ~Text3D();
     /// Register object factory. Drawable must be registered first.
     static void RegisterObject(Context* context);
-    
+
     /// Apply attribute changes that can not be applied immediately.
     virtual void ApplyAttributes();
     /// Calculate distance and prepare batches for rendering. May be called from worker thread(s), possibly re-entrantly.
@@ -53,7 +53,7 @@ public:
     virtual void UpdateGeometry(const FrameInfo& frame);
     /// Return whether a geometry update is necessary, and if it can happen in a worker thread.
     virtual UpdateGeometryType GetUpdateGeometryType();
-    
+
     /// Set font and font size and use signed distance field font. Return true if successful.
     bool SetFont(const String& fontName, int size = DEFAULT_FONT_SIZE);
     /// Set font and font size and use signed distance field font. Return true if successful.
@@ -90,7 +90,7 @@ public:
     void SetOpacity(float opacity);
     /// Set how the text should rotate in relation to the camera. Default is to not rotate (FC_NONE.)
     void SetFaceCameraMode(FaceCameraMode mode);
-    
+
     /// Return font.
     Font* GetFont() const;
     /// Return material.
@@ -135,24 +135,24 @@ public:
     float GetOpacity() const;
     /// Return how the text rotates in relation to the camera.
     FaceCameraMode GetFaceCameraMode() const { return faceCameraMode_; }
-    
+
     /// Set font attribute.
-    void SetFontAttr(ResourceRef value);
+    void SetFontAttr(const ResourceRef& value);
     /// Return font attribute.
     ResourceRef GetFontAttr() const;
     /// Set material attribute.
-    void SetMaterialAttr(ResourceRef value);
+    void SetMaterialAttr(const ResourceRef& value);
     /// Return material attribute.
     ResourceRef GetMaterialAttr() const;
     /// Get color attribute. Uses just the top-left color.
     const Color& GetColorAttr() const { return text_.color_[0]; }
-    
+
 protected:
     /// Handle node being assigned.
     virtual void OnNodeSet(Node* node);
     /// Recalculate the world-space bounding box.
     virtual void OnWorldBoundingBoxUpdate();
-    
+
 private:
     /// Mark text & geometry dirty.
     void MarkTextDirty();
@@ -162,7 +162,7 @@ private:
     void UpdateTextBatches();
     /// Create materials for text rendering. May only be called from the main thread. Text %UI batches must be up-to-date.
     void UpdateTextMaterials(bool forceUpdate = false);
-    
+
     /// Internally used text element.
     Text text_;
     /// Geometries.

+ 2 - 2
Source/Engine/UI/ToolTip.cpp

@@ -47,8 +47,8 @@ void ToolTip::RegisterObject(Context* context)
 {
     context->RegisterFactory<ToolTip>(UI_CATEGORY);
 
-    COPY_BASE_ATTRIBUTES(ToolTip, UIElement);
-    ACCESSOR_ATTRIBUTE(ToolTip, VAR_FLOAT, "Delay", GetDelay, SetDelay, float, 0.0f, AM_FILE);
+    COPY_BASE_ATTRIBUTES(UIElement);
+    ACCESSOR_ATTRIBUTE("Delay", GetDelay, SetDelay, float, 0.0f, AM_FILE);
 }
 
 void ToolTip::Update(float timeStep)

+ 1 - 1
Source/Engine/UI/UI.cpp

@@ -1078,7 +1078,7 @@ void UI::ProcessClickBegin(const IntVector2& cursorPos, int button, int buttons,
 
         bool newButton;
         if (usingTouchInput_)
-            newButton = !((bool)(button & buttons));
+            newButton = (button & buttons) == 0;
         else
             newButton = true;
         buttons |= button;

+ 32 - 52
Source/Engine/UI/UIElement.cpp

@@ -87,26 +87,6 @@ static bool CompareUIElements(const UIElement* lhs, const UIElement* rhs)
     return lhs->GetPriority() < rhs->GetPriority();
 }
 
-template<> HorizontalAlignment Variant::Get<HorizontalAlignment>() const
-{
-    return (HorizontalAlignment)GetInt();
-}
-
-template<> VerticalAlignment Variant::Get<VerticalAlignment>() const
-{
-    return (VerticalAlignment)GetInt();
-}
-
-template<> FocusMode Variant::Get<FocusMode>() const
-{
-    return (FocusMode)GetInt();
-}
-
-template<> LayoutMode Variant::Get<LayoutMode>() const
-{
-    return (LayoutMode)GetInt();
-}
-
 XPathQuery UIElement::styleXPathQuery_("/elements/element[@type=$typeName]", "typeName:String");
 
 UIElement::UIElement(Context* context) :
@@ -171,38 +151,38 @@ void UIElement::RegisterObject(Context* context)
 {
     context->RegisterFactory<UIElement>(UI_CATEGORY);
 
-    REF_ACCESSOR_ATTRIBUTE(UIElement, VAR_STRING, "Name", GetName, SetName, String, String::EMPTY, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(UIElement, VAR_INTVECTOR2, "Position", GetPosition, SetPosition, IntVector2, IntVector2::ZERO, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(UIElement, VAR_INTVECTOR2, "Size", GetSize, SetSize, IntVector2, IntVector2::ZERO, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(UIElement, VAR_INTVECTOR2, "Min Size", GetMinSize, SetMinSize, IntVector2, IntVector2::ZERO, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(UIElement, VAR_INTVECTOR2, "Max Size", GetMaxSize, SetMaxSize, IntVector2, IntVector2(M_MAX_INT, M_MAX_INT), AM_FILE);
-    ENUM_ACCESSOR_ATTRIBUTE(UIElement, "Horiz Alignment", GetHorizontalAlignment, SetHorizontalAlignment, HorizontalAlignment, horizontalAlignments, HA_LEFT, AM_FILE);
-    ENUM_ACCESSOR_ATTRIBUTE(UIElement, "Vert Alignment", GetVerticalAlignment, SetVerticalAlignment, VerticalAlignment, verticalAlignments, VA_TOP, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(UIElement, VAR_INTRECT, "Clip Border", GetClipBorder, SetClipBorder, IntRect, IntRect::ZERO, AM_FILE);
-    ACCESSOR_ATTRIBUTE(UIElement, VAR_INT, "Priority", GetPriority, SetPriority, int, 0, AM_FILE);
-    ACCESSOR_ATTRIBUTE(UIElement, VAR_FLOAT, "Opacity", GetOpacity, SetOpacity, float, 1.0f, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(UIElement, VAR_COLOR, "Color", GetColorAttr, SetColor, Color, Color::WHITE, AM_FILE);
-    ATTRIBUTE(UIElement, VAR_COLOR, "Top Left Color", color_[0], Color::WHITE, AM_FILE);
-    ATTRIBUTE(UIElement, VAR_COLOR, "Top Right Color", color_[1], Color::WHITE, AM_FILE);
-    ATTRIBUTE(UIElement, VAR_COLOR, "Bottom Left Color", color_[2], Color::WHITE, AM_FILE);
-    ATTRIBUTE(UIElement, VAR_COLOR, "Bottom Right Color", color_[3], Color::WHITE, AM_FILE);
-    ACCESSOR_ATTRIBUTE(UIElement, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, false, AM_FILE);
-    ACCESSOR_ATTRIBUTE(UIElement, VAR_BOOL, "Is Editable", IsEditable, SetEditable, bool, true, AM_FILE);
-    ACCESSOR_ATTRIBUTE(UIElement, VAR_BOOL, "Is Selected", IsSelected, SetSelected, bool, false, AM_FILE);
-    ACCESSOR_ATTRIBUTE(UIElement, VAR_BOOL, "Is Visible", IsVisible, SetVisible, bool, true, AM_FILE);
-    ACCESSOR_ATTRIBUTE(UIElement, VAR_BOOL, "Bring To Front", GetBringToFront, SetBringToFront, bool, false, AM_FILE);
-    ACCESSOR_ATTRIBUTE(UIElement, VAR_BOOL, "Bring To Back", GetBringToBack, SetBringToBack, bool, true, AM_FILE);
-    ACCESSOR_ATTRIBUTE(UIElement, VAR_BOOL, "Clip Children", GetClipChildren, SetClipChildren, bool, false, AM_FILE);
-    ACCESSOR_ATTRIBUTE(UIElement, VAR_BOOL, "Use Derived Opacity", GetUseDerivedOpacity, SetUseDerivedOpacity, bool, true, AM_FILE);
-    ENUM_ACCESSOR_ATTRIBUTE(UIElement, "Focus Mode", GetFocusMode, SetFocusMode, FocusMode, focusModes, FM_NOTFOCUSABLE, AM_FILE);
-    ENUM_ACCESSOR_ATTRIBUTE(UIElement, "Drag And Drop Mode", GetDragDropMode, SetDragDropMode, unsigned, dragDropModes, DD_DISABLED, AM_FILE);
-    ENUM_ACCESSOR_ATTRIBUTE(UIElement, "Layout Mode", GetLayoutMode, SetLayoutMode, LayoutMode, layoutModes, LM_FREE, AM_FILE);
-    ACCESSOR_ATTRIBUTE(UIElement, VAR_INT, "Layout Spacing", GetLayoutSpacing, SetLayoutSpacing, int, 0, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(UIElement, VAR_INTRECT, "Layout Border", GetLayoutBorder, SetLayoutBorder, IntRect, IntRect::ZERO, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(UIElement, VAR_VECTOR2, "Layout Flex Scale", GetLayoutFlexScale, SetLayoutFlexScale, Vector2, Vector2::ONE, AM_FILE);
-    ACCESSOR_ATTRIBUTE(UIElement, VAR_INT, "Indent", GetIndent, SetIndent, int, 0, AM_FILE);
-    ACCESSOR_ATTRIBUTE(UIElement, VAR_INT, "Indent Spacing", GetIndentSpacing, SetIndentSpacing, int, 16, AM_FILE);
-    ATTRIBUTE(UIElement, VAR_VARIANTMAP, "Variables", vars_, Variant::emptyVariantMap, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Name", GetName, SetName, String, String::EMPTY, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Position", GetPosition, SetPosition, IntVector2, IntVector2::ZERO, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Size", GetSize, SetSize, IntVector2, IntVector2::ZERO, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Min Size", GetMinSize, SetMinSize, IntVector2, IntVector2::ZERO, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Max Size", GetMaxSize, SetMaxSize, IntVector2, IntVector2(M_MAX_INT, M_MAX_INT), AM_FILE);
+    ENUM_ACCESSOR_ATTRIBUTE("Horiz Alignment", GetHorizontalAlignment, SetHorizontalAlignment, HorizontalAlignment, horizontalAlignments, HA_LEFT, AM_FILE);
+    ENUM_ACCESSOR_ATTRIBUTE("Vert Alignment", GetVerticalAlignment, SetVerticalAlignment, VerticalAlignment, verticalAlignments, VA_TOP, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Clip Border", GetClipBorder, SetClipBorder, IntRect, IntRect::ZERO, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Priority", GetPriority, SetPriority, int, 0, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Opacity", GetOpacity, SetOpacity, float, 1.0f, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Color", GetColorAttr, SetColor, Color, Color::WHITE, AM_FILE);
+    ATTRIBUTE("Top Left Color", Color, color_[0], Color::WHITE, AM_FILE);
+    ATTRIBUTE("Top Right Color", Color, color_[1], Color::WHITE, AM_FILE);
+    ATTRIBUTE("Bottom Left Color", Color, color_[2], Color::WHITE, AM_FILE);
+    ATTRIBUTE("Bottom Right Color", Color, color_[3], Color::WHITE, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, false, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Is Editable", IsEditable, SetEditable, bool, true, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Is Selected", IsSelected, SetSelected, bool, false, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Is Visible", IsVisible, SetVisible, bool, true, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Bring To Front", GetBringToFront, SetBringToFront, bool, false, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Bring To Back", GetBringToBack, SetBringToBack, bool, true, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Clip Children", GetClipChildren, SetClipChildren, bool, false, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Use Derived Opacity", GetUseDerivedOpacity, SetUseDerivedOpacity, bool, true, AM_FILE);
+    ENUM_ACCESSOR_ATTRIBUTE("Focus Mode", GetFocusMode, SetFocusMode, FocusMode, focusModes, FM_NOTFOCUSABLE, AM_FILE);
+    ENUM_ACCESSOR_ATTRIBUTE("Drag And Drop Mode", GetDragDropMode, SetDragDropMode, unsigned, dragDropModes, DD_DISABLED, AM_FILE);
+    ENUM_ACCESSOR_ATTRIBUTE("Layout Mode", GetLayoutMode, SetLayoutMode, LayoutMode, layoutModes, LM_FREE, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Layout Spacing", GetLayoutSpacing, SetLayoutSpacing, int, 0, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Layout Border", GetLayoutBorder, SetLayoutBorder, IntRect, IntRect::ZERO, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Layout Flex Scale", GetLayoutFlexScale, SetLayoutFlexScale, Vector2, Vector2::ONE, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Indent", GetIndent, SetIndent, int, 0, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Indent Spacing", GetIndentSpacing, SetIndentSpacing, int, 16, AM_FILE);
+    ATTRIBUTE("Variables", VariantMap, vars_, Variant::emptyVariantMap, AM_FILE);
 }
 
 void UIElement::ApplyAttributes()

+ 4 - 4
Source/Engine/UI/View3D.cpp

@@ -56,11 +56,11 @@ void View3D::RegisterObject(Context* context)
 {
     context->RegisterFactory<View3D>(UI_CATEGORY);
 
-    COPY_BASE_ATTRIBUTES(View3D, Window);
+    COPY_BASE_ATTRIBUTES(Window);
     // The texture format is API specific, so do not register it as a serializable attribute
-    ACCESSOR_ATTRIBUTE(View3D, VAR_BOOL, "Auto Update", GetAutoUpdate, SetAutoUpdate, bool, true, AM_FILE);
-    UPDATE_ATTRIBUTE_DEFAULT_VALUE(View3D, "Clip Children", true);
-    UPDATE_ATTRIBUTE_DEFAULT_VALUE(View3D, "Is Enabled", true);
+    ACCESSOR_ATTRIBUTE("Auto Update", GetAutoUpdate, SetAutoUpdate, bool, true, AM_FILE);
+    UPDATE_ATTRIBUTE_DEFAULT_VALUE("Clip Children", true);
+    UPDATE_ATTRIBUTE_DEFAULT_VALUE("Is Enabled", true);
 }
 
 void View3D::OnResize()

+ 13 - 13
Source/Engine/UI/Window.cpp

@@ -65,20 +65,20 @@ void Window::RegisterObject(Context* context)
 {
     context->RegisterFactory<Window>(UI_CATEGORY);
 
-    COPY_BASE_ATTRIBUTES(Window, BorderImage);
-    UPDATE_ATTRIBUTE_DEFAULT_VALUE(Window, "Bring To Front", true);
-    UPDATE_ATTRIBUTE_DEFAULT_VALUE(Window, "Clip Children", true);
-    UPDATE_ATTRIBUTE_DEFAULT_VALUE(Window, "Is Enabled", true);
-    REF_ACCESSOR_ATTRIBUTE(Window, VAR_INTRECT, "Resize Border", GetResizeBorder, SetResizeBorder, IntRect, IntRect(DEFAULT_RESIZE_BORDER, \
+    COPY_BASE_ATTRIBUTES(BorderImage);
+    UPDATE_ATTRIBUTE_DEFAULT_VALUE("Bring To Front", true);
+    UPDATE_ATTRIBUTE_DEFAULT_VALUE("Clip Children", true);
+    UPDATE_ATTRIBUTE_DEFAULT_VALUE("Is Enabled", true);
+    ACCESSOR_ATTRIBUTE("Resize Border", GetResizeBorder, SetResizeBorder, IntRect, IntRect(DEFAULT_RESIZE_BORDER, \
         DEFAULT_RESIZE_BORDER, DEFAULT_RESIZE_BORDER, DEFAULT_RESIZE_BORDER), AM_FILE);
-    ACCESSOR_ATTRIBUTE(Window, VAR_BOOL, "Is Movable", IsMovable, SetMovable, bool, false, AM_FILE);
-    ACCESSOR_ATTRIBUTE(Window, VAR_BOOL, "Is Resizable", IsResizable, SetResizable, bool, false, AM_FILE);
-    ACCESSOR_ATTRIBUTE(Window, VAR_BOOL, "Fixed Width Resizing", GetFixedWidthResizing, SetFixedWidthResizing, bool, false, AM_FILE);
-    ACCESSOR_ATTRIBUTE(Window, VAR_BOOL, "Fixed Height Resizing", GetFixedHeightResizing, SetFixedHeightResizing, bool, false, AM_FILE);
-    ACCESSOR_ATTRIBUTE(Window, VAR_BOOL, "Is Modal", IsModal, SetModal, bool, false, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(Window, VAR_COLOR, "Modal Shade Color", GetModalShadeColor, SetModalShadeColor, Color, Color::TRANSPARENT, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(Window, VAR_COLOR, "Modal Frame Color", GetModalFrameColor, SetModalFrameColor, Color, Color::TRANSPARENT, AM_FILE);
-    REF_ACCESSOR_ATTRIBUTE(Window, VAR_INTVECTOR2, "Modal Frame Size", GetModalFrameSize, SetModalFrameSize, IntVector2, IntVector2::ZERO, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Is Movable", IsMovable, SetMovable, bool, false, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Is Resizable", IsResizable, SetResizable, bool, false, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Fixed Width Resizing", GetFixedWidthResizing, SetFixedWidthResizing, bool, false, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Fixed Height Resizing", GetFixedHeightResizing, SetFixedHeightResizing, bool, false, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Is Modal", IsModal, SetModal, bool, false, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Modal Shade Color", GetModalShadeColor, SetModalShadeColor, Color, Color::TRANSPARENT, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Modal Frame Color", GetModalFrameColor, SetModalFrameColor, Color, Color::TRANSPARENT, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Modal Frame Size", GetModalFrameSize, SetModalFrameSize, IntVector2, IntVector2::ZERO, AM_FILE);
     // Modal auto dismiss is purposefully not an attribute, as using it can make the editor lock up.
     // Instead it should be set false in code when needed
 }

+ 12 - 17
Source/Engine/Urho2D/AnimatedSprite2D.cpp

@@ -48,11 +48,6 @@ const char* loopModeNames[] =
     0
 };
 
-template<> LoopMode2D Variant::Get<LoopMode2D>() const
-{
-    return (LoopMode2D)GetInt();
-}
-
 AnimatedSprite2D::AnimatedSprite2D(Context* context) :
     Drawable(context, DRAWABLE_GEOMETRY),
     layer_(0),
@@ -75,17 +70,17 @@ AnimatedSprite2D::~AnimatedSprite2D()
 void AnimatedSprite2D::RegisterObject(Context* context)
 {
     context->RegisterFactory<AnimatedSprite2D>(URHO2D_CATEGORY);
-    ACCESSOR_ATTRIBUTE(AnimatedSprite2D, VAR_INT, "Layer", GetLayer, SetLayer, int, 0, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(AnimatedSprite2D, VAR_INT, "Order in Layer", GetOrderInLayer, SetOrderInLayer, int, 0, AM_DEFAULT);
-    ENUM_ACCESSOR_ATTRIBUTE(AnimatedSprite2D, "Blend Mode", GetBlendMode, SetBlendMode, BlendMode, blendModeNames, BLEND_ALPHA, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(AnimatedSprite2D, VAR_BOOL, "Flip X", GetFlipX, SetFlipX, bool, false, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(AnimatedSprite2D, VAR_BOOL, "Flip Y", GetFlipY, SetFlipY, bool, false, AM_DEFAULT);
-    REF_ACCESSOR_ATTRIBUTE(AnimatedSprite2D, VAR_COLOR, "Color", GetColor, SetColor, Color, Color::WHITE, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(AnimatedSprite2D, VAR_FLOAT, "Speed", GetSpeed, SetSpeed, float, 1.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(AnimatedSprite2D, VAR_RESOURCEREF, "Animation Set", GetAnimationSetAttr, SetAnimationSetAttr, ResourceRef, ResourceRef(AnimatedSprite2D::GetTypeStatic()), AM_DEFAULT);
-    REF_ACCESSOR_ATTRIBUTE(AnimatedSprite2D, VAR_STRING, "Animation", GetAnimation, SetAnimationAttr, String, String::EMPTY, AM_DEFAULT);
-    ENUM_ACCESSOR_ATTRIBUTE(AnimatedSprite2D, "Loop Mode", GetLoopMode, SetLoopMode, LoopMode2D, loopModeNames, LM_DEFAULT, AM_DEFAULT);
-    COPY_BASE_ATTRIBUTES(AnimatedSprite2D, Drawable);
+    ACCESSOR_ATTRIBUTE("Layer", GetLayer, SetLayer, int, 0, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Order in Layer", GetOrderInLayer, SetOrderInLayer, int, 0, AM_DEFAULT);
+    ENUM_ACCESSOR_ATTRIBUTE("Blend Mode", GetBlendMode, SetBlendMode, BlendMode, blendModeNames, BLEND_ALPHA, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Flip X", GetFlipX, SetFlipX, bool, false, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Flip Y", GetFlipY, SetFlipY, bool, false, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Color", GetColor, SetColor, Color, Color::WHITE, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Speed", GetSpeed, SetSpeed, float, 1.0f, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Animation Set", GetAnimationSetAttr, SetAnimationSetAttr, ResourceRef, ResourceRef(AnimatedSprite2D::GetTypeStatic()), AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Animation", GetAnimation, SetAnimationAttr, String, String::EMPTY, AM_DEFAULT);
+    ENUM_ACCESSOR_ATTRIBUTE("Loop Mode", GetLoopMode, SetLoopMode, LoopMode2D, loopModeNames, LM_DEFAULT, AM_DEFAULT);
+    COPY_BASE_ATTRIBUTES(Drawable);
 }
 
 void AnimatedSprite2D::OnSetEnabled()
@@ -244,7 +239,7 @@ Node* AnimatedSprite2D::GetRootNode() const
     return rootNode_;
 }
 
-void AnimatedSprite2D::SetAnimationSetAttr(ResourceRef value)
+void AnimatedSprite2D::SetAnimationSetAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SetAnimationSet(cache->GetResource<AnimationSet2D>(value.name_));

+ 2 - 2
Source/Engine/Urho2D/AnimatedSprite2D.h

@@ -56,7 +56,7 @@ public:
 
     /// Handle enabled/disabled state change.
     virtual void OnSetEnabled();
-    
+
     /// Set layer.
     void SetLayer(int layer);
     /// Set order in layer.
@@ -106,7 +106,7 @@ public:
     Node* GetRootNode() const;
 
     /// Set animation set attribute.
-    void SetAnimationSetAttr(ResourceRef value);
+    void SetAnimationSetAttr(const ResourceRef& value);
     /// Return animation set attribute.
     ResourceRef GetAnimationSetAttr() const;
     /// Set anmiation by name.

+ 4 - 4
Source/Engine/Urho2D/CollisionBox2D.cpp

@@ -53,10 +53,10 @@ void CollisionBox2D::RegisterObject(Context* context)
 {
     context->RegisterFactory<CollisionBox2D>(URHO2D_CATEGORY);
 
-    REF_ACCESSOR_ATTRIBUTE(CollisionBox2D, VAR_VECTOR2, "Size", GetSize, SetSize, Vector2, DEFAULT_BOX_SIZE, AM_DEFAULT);
-    REF_ACCESSOR_ATTRIBUTE(CollisionBox2D, VAR_VECTOR2, "Center", GetCenter, SetCenter, Vector2, Vector2::ZERO, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(CollisionBox2D, VAR_FLOAT, "Angle", GetAngle, SetAngle, float, 0.0f, AM_DEFAULT);
-    COPY_BASE_ATTRIBUTES(CollisionBox2D, CollisionShape2D);
+    ACCESSOR_ATTRIBUTE("Size", GetSize, SetSize, Vector2, DEFAULT_BOX_SIZE, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Center", GetCenter, SetCenter, Vector2, Vector2::ZERO, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Angle", GetAngle, SetAngle, float, 0.0f, AM_DEFAULT);
+    COPY_BASE_ATTRIBUTES(CollisionShape2D);
 }
 
 void CollisionBox2D::SetSize(const Vector2& size)

+ 2 - 2
Source/Engine/Urho2D/CollisionChain2D.cpp

@@ -44,8 +44,8 @@ CollisionChain2D::~CollisionChain2D()
 void CollisionChain2D::RegisterObject(Context* context)
 {
     context->RegisterFactory<CollisionChain2D>();
-    ACCESSOR_ATTRIBUTE(CollisionChain2D, VAR_BOOL, "Loop", GetLoop, SetLoop, bool, false, AM_DEFAULT);
-    COPY_BASE_ATTRIBUTES(CollisionChain2D, CollisionShape2D);
+    ACCESSOR_ATTRIBUTE("Loop", GetLoop, SetLoop, bool, false, AM_DEFAULT);
+    COPY_BASE_ATTRIBUTES(CollisionShape2D);
 }
 
 void CollisionChain2D::SetLoop(bool loop)

+ 3 - 3
Source/Engine/Urho2D/CollisionCircle2D.cpp

@@ -50,9 +50,9 @@ void CollisionCircle2D::RegisterObject(Context* context)
 {
     context->RegisterFactory<CollisionCircle2D>(URHO2D_CATEGORY);
 
-    ACCESSOR_ATTRIBUTE(CollisionCircle2D, VAR_FLOAT, "Radius", GetRadius, SetRadius, float, DEFAULT_CLRCLE_RADIUS, AM_DEFAULT);
-    REF_ACCESSOR_ATTRIBUTE(CollisionCircle2D, VAR_VECTOR2, "Center", GetCenter, SetCenter, Vector2, Vector2::ZERO, AM_DEFAULT);
-    COPY_BASE_ATTRIBUTES(CollisionCircle2D, CollisionShape2D);
+    ACCESSOR_ATTRIBUTE("Radius", GetRadius, SetRadius, float, DEFAULT_CLRCLE_RADIUS, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Center", GetCenter, SetCenter, Vector2, Vector2::ZERO, AM_DEFAULT);
+    COPY_BASE_ATTRIBUTES(CollisionShape2D);
 }
 
 void CollisionCircle2D::SetRadius(float radius)

+ 3 - 3
Source/Engine/Urho2D/CollisionEdge2D.cpp

@@ -54,9 +54,9 @@ void CollisionEdge2D::RegisterObject(Context* context)
 {
     context->RegisterFactory<CollisionEdge2D>(URHO2D_CATEGORY);
 
-    REF_ACCESSOR_ATTRIBUTE(CollisionEdge2D, VAR_VECTOR2, "Vertex 1", GetVertex1, SetVertex1, Vector2, DEFAULT_VERTEX1, AM_DEFAULT);
-    REF_ACCESSOR_ATTRIBUTE(CollisionEdge2D, VAR_VECTOR2, "Vertex 2", GetVertex2, SetVertex2, Vector2, DEFAULT_VERTEX2, AM_DEFAULT);
-    COPY_BASE_ATTRIBUTES(CollisionEdge2D, CollisionShape2D);
+    ACCESSOR_ATTRIBUTE("Vertex 1", GetVertex1, SetVertex1, Vector2, DEFAULT_VERTEX1, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Vertex 2", GetVertex2, SetVertex2, Vector2, DEFAULT_VERTEX2, AM_DEFAULT);
+    COPY_BASE_ATTRIBUTES(CollisionShape2D);
 }
 
 void CollisionEdge2D::SetVertex1(const Vector2& vertex)

+ 1 - 1
Source/Engine/Urho2D/CollisionPolygon2D.cpp

@@ -45,7 +45,7 @@ CollisionPolygon2D::~CollisionPolygon2D()
 void CollisionPolygon2D::RegisterObject(Context* context)
 {
     context->RegisterFactory<CollisionPolygon2D>(URHO2D_CATEGORY);
-    COPY_BASE_ATTRIBUTES(CollisionPolygon2D, CollisionShape2D);
+    COPY_BASE_ATTRIBUTES(CollisionShape2D);
 }
 
 void CollisionPolygon2D::SetVertexCount(unsigned count)

+ 9 - 9
Source/Engine/Urho2D/CollisionShape2D.cpp

@@ -54,15 +54,15 @@ CollisionShape2D::~CollisionShape2D()
 
 void CollisionShape2D::RegisterObject(Context* context)
 {
-    ACCESSOR_ATTRIBUTE(CollisionShape2D, VAR_BOOL, "Trigger", IsTrigger, SetTrigger, bool, false, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(CollisionShape2D, VAR_INT, "Category Bits", GetCategoryBits, SetCategoryBits, int, 0, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(CollisionShape2D, VAR_INT, "Mask Bits", GetMaskBits, SetMaskBits, int, 0, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(CollisionShape2D, VAR_INT, "Group Index", GetGroupIndex, SetGroupIndex, int, 0, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(CollisionShape2D, VAR_FLOAT, "Density", GetDensity, SetDensity, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(CollisionShape2D, VAR_FLOAT, "Friction", GetFriction, SetFriction, float, 0.2f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(CollisionShape2D, VAR_FLOAT, "Restitution", GetRestitution, SetRestitution, float, 0.0f, AM_DEFAULT);
-
-    COPY_BASE_ATTRIBUTES(CollisionShape2D, Component);
+    ACCESSOR_ATTRIBUTE("Trigger", IsTrigger, SetTrigger, bool, false, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Category Bits", GetCategoryBits, SetCategoryBits, int, 0, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Mask Bits", GetMaskBits, SetMaskBits, int, 0, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Group Index", GetGroupIndex, SetGroupIndex, int, 0, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Density", GetDensity, SetDensity, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Friction", GetFriction, SetFriction, float, 0.2f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Restitution", GetRestitution, SetRestitution, float, 0.0f, AM_DEFAULT);
+
+    COPY_BASE_ATTRIBUTES(Component);
 }
 
 void CollisionShape2D::OnSetEnabled()

+ 2 - 2
Source/Engine/Urho2D/Constraint2D.cpp

@@ -58,8 +58,8 @@ Constraint2D::~Constraint2D()
 
 void Constraint2D::RegisterObject(Context* context)
 {
-    ACCESSOR_ATTRIBUTE(Constraint2D, VAR_BOOL, "Collide Connected", GetCollideConnected, SetCollideConnected, bool, false, AM_DEFAULT);
-    COPY_BASE_ATTRIBUTES(Constraint2D, Component);
+    ACCESSOR_ATTRIBUTE("Collide Connected", GetCollideConnected, SetCollideConnected, bool, false, AM_DEFAULT);
+    COPY_BASE_ATTRIBUTES(Component);
 }
 
 void Constraint2D::OnSetEnabled()

+ 5 - 5
Source/Engine/Urho2D/ConstraintDistance2D.cpp

@@ -47,11 +47,11 @@ void ConstraintDistance2D::RegisterObject(Context* context)
 {
     context->RegisterFactory<ConstraintDistance2D>();
     
-    REF_ACCESSOR_ATTRIBUTE(ConstraintDistance2D, VAR_VECTOR2, "Owner Body Anchor", GetOwnerBodyAnchor, SetOwnerBodyAnchor, Vector2, Vector2::ZERO, AM_DEFAULT);
-    REF_ACCESSOR_ATTRIBUTE(ConstraintDistance2D, VAR_VECTOR2, "Other Body Anchor", GetOtherBodyAnchor, SetOtherBodyAnchor, Vector2, Vector2::ZERO, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(ConstraintDistance2D, VAR_FLOAT, "Frequency Hz", GetFrequencyHz, SetFrequencyHz, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(ConstraintDistance2D, VAR_FLOAT, "Damping Ratio", GetDampingRatio, SetDampingRatio, float, 0.0f, AM_DEFAULT);
-    COPY_BASE_ATTRIBUTES(ConstraintDistance2D, Constraint2D);
+    ACCESSOR_ATTRIBUTE("Owner Body Anchor", GetOwnerBodyAnchor, SetOwnerBodyAnchor, Vector2, Vector2::ZERO, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Other Body Anchor", GetOtherBodyAnchor, SetOtherBodyAnchor, Vector2, Vector2::ZERO, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Frequency Hz", GetFrequencyHz, SetFrequencyHz, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Damping Ratio", GetDampingRatio, SetDampingRatio, float, 0.0f, AM_DEFAULT);
+    COPY_BASE_ATTRIBUTES(Constraint2D);
 }
 
 void ConstraintDistance2D::SetOwnerBodyAnchor(const Vector2& anchor)

+ 4 - 4
Source/Engine/Urho2D/ConstraintFriction2D.cpp

@@ -46,10 +46,10 @@ void ConstraintFriction2D::RegisterObject(Context* context)
 {
     context->RegisterFactory<ConstraintFriction2D>();
     
-    REF_ACCESSOR_ATTRIBUTE(ConstraintFriction2D, VAR_VECTOR2, "Anchor", GetAnchor, SetAnchor, Vector2, Vector2::ZERO, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(ConstraintFriction2D, VAR_FLOAT, "Max Force", GetMaxForce, SetMaxForce, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(ConstraintFriction2D, VAR_FLOAT, "Max Torque", GetMaxTorque, SetMaxTorque, float, 0.0f, AM_DEFAULT);
-    COPY_BASE_ATTRIBUTES(ConstraintFriction2D, Constraint2D);
+    ACCESSOR_ATTRIBUTE("Anchor", GetAnchor, SetAnchor, Vector2, Vector2::ZERO, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Max Force", GetMaxForce, SetMaxForce, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE("Max Torque", GetMaxTorque, SetMaxTorque, float, 0.0f, AM_DEFAULT);
+    COPY_BASE_ATTRIBUTES(Constraint2D);
 }
 
 void ConstraintFriction2D::SetAnchor(const Vector2& anchor)

Some files were not shown because too many files changed in this diff