Browse Source

Add MIXED_ACCESSOR_ATTRIBUTE.

aster2013 11 years ago
parent
commit
7e46f0c862
67 changed files with 1062 additions and 1024 deletions
  1. 18 18
      Source/Engine/Audio/SoundSource.cpp
  2. 9 9
      Source/Engine/Audio/SoundSource.h
  3. 12 12
      Source/Engine/Graphics/AnimatedModel.cpp
  4. 3 3
      Source/Engine/Graphics/AnimatedModel.h
  5. 55 56
      Source/Engine/Graphics/AnimationController.cpp
  6. 10 10
      Source/Engine/Graphics/AnimationController.h
  7. 52 52
      Source/Engine/Graphics/BillboardSet.cpp
  8. 11 11
      Source/Engine/Graphics/BillboardSet.h
  9. 14 14
      Source/Engine/Graphics/Camera.cpp
  10. 10 10
      Source/Engine/Graphics/Camera.h
  11. 50 50
      Source/Engine/Graphics/CustomGeometry.cpp
  12. 6 6
      Source/Engine/Graphics/CustomGeometry.h
  13. 130 130
      Source/Engine/Graphics/DecalSet.cpp
  14. 15 15
      Source/Engine/Graphics/DecalSet.h
  15. 9 9
      Source/Engine/Graphics/Light.cpp
  16. 21 21
      Source/Engine/Graphics/Light.h
  17. 14 14
      Source/Engine/Graphics/ParticleEmitter.cpp
  18. 3 3
      Source/Engine/Graphics/ParticleEmitter.h
  19. 41 41
      Source/Engine/Graphics/StaticModel.cpp
  20. 9 9
      Source/Engine/Graphics/StaticModel.h
  21. 33 33
      Source/Engine/Graphics/Terrain.cpp
  22. 3 3
      Source/Engine/Graphics/Terrain.h
  23. 4 4
      Source/Engine/Graphics/Zone.cpp
  24. 8 8
      Source/Engine/Graphics/Zone.h
  25. 8 8
      Source/Engine/LuaScript/LuaScriptInstance.cpp
  26. 3 3
      Source/Engine/LuaScript/LuaScriptInstance.h
  27. 1 1
      Source/Engine/LuaScript/pkgs/Physics/PhysicsWorld.pkg
  28. 7 7
      Source/Engine/LuaScript/pkgs/Physics/RigidBody.pkg
  29. 1 1
      Source/Engine/LuaScript/pkgs/Scene/Scene.pkg
  30. 2 2
      Source/Engine/LuaScript/pkgs/Urho2D/RigidBody2D.pkg
  31. 160 160
      Source/Engine/Navigation/NavigationMesh.cpp
  32. 8 8
      Source/Engine/Navigation/NavigationMesh.h
  33. 8 8
      Source/Engine/Physics/CollisionShape.cpp
  34. 12 12
      Source/Engine/Physics/CollisionShape.h
  35. 14 14
      Source/Engine/Physics/PhysicsWorld.cpp
  36. 3 3
      Source/Engine/Physics/PhysicsWorld.h
  37. 15 15
      Source/Engine/Physics/RigidBody.cpp
  38. 15 15
      Source/Engine/Physics/RigidBody.h
  39. 2 2
      Source/Engine/Scene/Animatable.cpp
  40. 1 1
      Source/Engine/Scene/Animatable.h
  41. 26 26
      Source/Engine/Scene/Scene.cpp
  42. 1 1
      Source/Engine/Scene/Scene.h
  43. 39 0
      Source/Engine/Scene/Serializable.h
  44. 12 12
      Source/Engine/Script/PhysicsAPI.cpp
  45. 8 8
      Source/Engine/Script/ScriptInstance.cpp
  46. 11 11
      Source/Engine/Script/ScriptInstance.h
  47. 3 3
      Source/Engine/Script/Urho2DAPI.cpp
  48. 2 2
      Source/Engine/UI/BorderImage.cpp
  49. 8 8
      Source/Engine/UI/BorderImage.h
  50. 7 7
      Source/Engine/UI/Cursor.cpp
  51. 8 8
      Source/Engine/UI/Cursor.h
  52. 19 19
      Source/Engine/UI/Sprite.cpp
  53. 7 7
      Source/Engine/UI/Sprite.h
  54. 21 21
      Source/Engine/UI/Text.cpp
  55. 1 1
      Source/Engine/UI/Text.h
  56. 44 44
      Source/Engine/UI/Text3D.cpp
  57. 10 10
      Source/Engine/UI/Text3D.h
  58. 2 2
      Source/Engine/Urho2D/AnimatedSprite2D.cpp
  59. 2 2
      Source/Engine/Urho2D/AnimatedSprite2D.h
  60. 4 4
      Source/Engine/Urho2D/Drawable2D.cpp
  61. 2 2
      Source/Engine/Urho2D/Drawable2D.h
  62. 11 11
      Source/Engine/Urho2D/ParticleEmitter2D.cpp
  63. 2 2
      Source/Engine/Urho2D/ParticleEmitter2D.h
  64. 5 5
      Source/Engine/Urho2D/RigidBody2D.cpp
  65. 4 4
      Source/Engine/Urho2D/RigidBody2D.h
  66. 2 2
      Source/Engine/Urho2D/TileMap2D.cpp
  67. 1 1
      Source/Engine/Urho2D/TileMap2D.h

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

@@ -137,7 +137,7 @@ void SoundSource::RegisterObject(Context* context)
     context->RegisterFactory<SoundSource>(AUDIO_CATEGORY);
     context->RegisterFactory<SoundSource>(AUDIO_CATEGORY);
 
 
     ACCESSOR_ATTRIBUTE(SoundSource, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
     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);
+    MIXED_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);
     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, "Frequency", frequency_, 0.0f, AM_DEFAULT);
     ATTRIBUTE(SoundSource, VAR_FLOAT, "Gain", gain_, 1.0f, AM_DEFAULT);
     ATTRIBUTE(SoundSource, VAR_FLOAT, "Gain", gain_, 1.0f, AM_DEFAULT);
@@ -152,7 +152,7 @@ void SoundSource::Play(Sound* sound)
 {
 {
     if (!audio_)
     if (!audio_)
         return;
         return;
-    
+
     // If no frequency set yet, set from the sound's default
     // If no frequency set yet, set from the sound's default
     if (frequency_ == 0.0f && sound)
     if (frequency_ == 0.0f && sound)
         SetFrequency(sound->GetFrequency());
         SetFrequency(sound->GetFrequency());
@@ -200,7 +200,7 @@ void SoundSource::Play(SoundStream* stream)
         SetFrequency(stream->GetFrequency());
         SetFrequency(stream->GetFrequency());
 
 
     SharedPtr<SoundStream> streamPtr(stream);
     SharedPtr<SoundStream> streamPtr(stream);
-    
+
     // If sound source is currently playing, have to lock the audio mutex. When stream playback is explicitly
     // If sound source is currently playing, have to lock the audio mutex. When stream playback is explicitly
     // requested, clear the existing sound if any
     // requested, clear the existing sound if any
     if (position_)
     if (position_)
@@ -214,7 +214,7 @@ void SoundSource::Play(SoundStream* stream)
         sound_.Reset();
         sound_.Reset();
         PlayLockless(streamPtr);
         PlayLockless(streamPtr);
     }
     }
-    
+
     // Stream playback is not supported for network replication, no need to mark network dirty
     // Stream playback is not supported for network replication, no need to mark network dirty
 }
 }
 
 
@@ -231,7 +231,7 @@ void SoundSource::Stop()
     }
     }
     else
     else
         StopLockless();
         StopLockless();
-    
+
     MarkNetworkUpdate();
     MarkNetworkUpdate();
 }
 }
 
 
@@ -323,9 +323,9 @@ void SoundSource::Mix(int* dest, unsigned samples, int mixRate, bool stereo, boo
 {
 {
     if (!position_ || (!sound_ && !soundStream_) || !IsEnabledEffective())
     if (!position_ || (!sound_ && !soundStream_) || !IsEnabledEffective())
         return;
         return;
-    
+
     int streamFilledSize, outBytes;
     int streamFilledSize, outBytes;
-    
+
     if (soundStream_ && streamBuffer_)
     if (soundStream_ && streamBuffer_)
     {
     {
         int streamBufferSize = streamBuffer_->GetDataSize();
         int streamBufferSize = streamBuffer_->GetDataSize();
@@ -336,10 +336,10 @@ void SoundSource::Mix(int* dest, unsigned samples, int mixRate, bool stereo, boo
         neededSize *= soundStream_->GetSampleSize();
         neededSize *= soundStream_->GetSampleSize();
         neededSize -= unusedStreamSize_;
         neededSize -= unusedStreamSize_;
         neededSize = Clamp(neededSize, 0, streamBufferSize - unusedStreamSize_);
         neededSize = Clamp(neededSize, 0, streamBufferSize - unusedStreamSize_);
-        
+
         // Always start play position at the beginning of the stream buffer
         // Always start play position at the beginning of the stream buffer
         position_ = streamBuffer_->GetStart();
         position_ = streamBuffer_->GetStart();
-        
+
         // Request new data from the stream
         // Request new data from the stream
         signed char* dest = streamBuffer_->GetStart() + unusedStreamSize_;
         signed char* dest = streamBuffer_->GetStart() + unusedStreamSize_;
         outBytes = neededSize ? soundStream_->GetData(dest, neededSize) : 0;
         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
         // Zero-fill rest if stream did not produce enough data
         if (outBytes < neededSize)
         if (outBytes < neededSize)
             memset(dest, 0, neededSize - outBytes);
             memset(dest, 0, neededSize - outBytes);
-        
+
         // Calculate amount of total bytes of data in stream buffer now, to know how much went unused after mixing
         // Calculate amount of total bytes of data in stream buffer now, to know how much went unused after mixing
         streamFilledSize = neededSize + unusedStreamSize_;
         streamFilledSize = neededSize + unusedStreamSize_;
     }
     }
@@ -397,11 +397,11 @@ void SoundSource::Mix(int* dest, unsigned samples, int mixRate, bool stereo, boo
     if (soundStream_)
     if (soundStream_)
     {
     {
         timePosition_ += ((float)samples / (float)mixRate) * frequency_ / soundStream_->GetFrequency();
         timePosition_ += ((float)samples / (float)mixRate) * frequency_ / soundStream_->GetFrequency();
-        
+
         unusedStreamSize_ = Max(streamFilledSize - (int)(size_t)(position_ - streamBuffer_->GetStart()), 0);
         unusedStreamSize_ = Max(streamFilledSize - (int)(size_t)(position_ - streamBuffer_->GetStart()), 0);
         if (unusedStreamSize_)
         if (unusedStreamSize_)
             memcpy(streamBuffer_->GetStart(), (const void*)position_, unusedStreamSize_);
             memcpy(streamBuffer_->GetStart(), (const void*)position_, unusedStreamSize_);
-        
+
         // If stream did not produce any data, stop if applicable
         // If stream did not produce any data, stop if applicable
         if (!outBytes && soundStream_->GetStopAtEnd())
         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());
         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>();
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     Sound* newSound = cache->GetResource<Sound>(value.name_);
     Sound* newSound = cache->GetResource<Sound>(value.name_);
@@ -488,7 +488,7 @@ void SoundSource::PlayLockless(Sound* sound)
             return;
             return;
         }
         }
     }
     }
-    
+
     // If sound pointer is null or if sound has no data, stop playback
     // If sound pointer is null or if sound has no data, stop playback
     StopLockless();
     StopLockless();
     sound_.Reset();
     sound_.Reset();
@@ -504,19 +504,19 @@ void SoundSource::PlayLockless(SharedPtr<SoundStream> stream)
         // Setup the stream buffer
         // Setup the stream buffer
         unsigned sampleSize = stream->GetSampleSize();
         unsigned sampleSize = stream->GetSampleSize();
         unsigned streamBufferSize = sampleSize * stream->GetIntFrequency() * STREAM_BUFFER_LENGTH / 1000;
         unsigned streamBufferSize = sampleSize * stream->GetIntFrequency() * STREAM_BUFFER_LENGTH / 1000;
-        
+
         streamBuffer_ = new Sound(context_);
         streamBuffer_ = new Sound(context_);
         streamBuffer_->SetSize(streamBufferSize);
         streamBuffer_->SetSize(streamBufferSize);
         streamBuffer_->SetFormat(stream->GetIntFrequency(), stream->IsSixteenBit(), stream->IsStereo());
         streamBuffer_->SetFormat(stream->GetIntFrequency(), stream->IsSixteenBit(), stream->IsStereo());
         streamBuffer_->SetLooped(true);
         streamBuffer_->SetLooped(true);
-        
+
         soundStream_ = stream;
         soundStream_ = stream;
         unusedStreamSize_ = 0;
         unusedStreamSize_ = 0;
         position_ = streamBuffer_->GetStart();
         position_ = streamBuffer_->GetStart();
         fractPosition_ = 0;
         fractPosition_ = 0;
         return;
         return;
     }
     }
-    
+
     // If stream pointer is null, stop playback
     // If stream pointer is null, stop playback
     StopLockless();
     StopLockless();
 }
 }
@@ -525,7 +525,7 @@ void SoundSource::StopLockless()
 {
 {
     position_ = 0;
     position_ = 0;
     timePosition_ = 0.0f;
     timePosition_ = 0.0f;
-    
+
     // Free the sound stream and decode buffer if a stream was playing
     // Free the sound stream and decode buffer if a stream was playing
     soundStream_.Reset();
     soundStream_.Reset();
     streamBuffer_.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
 class URHO3D_API SoundSource : public Component
 {
 {
     OBJECT(SoundSource);
     OBJECT(SoundSource);
-    
+
 public:
 public:
     /// Construct.
     /// Construct.
     SoundSource(Context* context);
     SoundSource(Context* context);
@@ -47,7 +47,7 @@ public:
     virtual ~SoundSource();
     virtual ~SoundSource();
     /// Register object factory.
     /// Register object factory.
     static void RegisterObject(Context* context);
     static void RegisterObject(Context* context);
-    
+
     /// Play a sound.
     /// Play a sound.
     void Play(Sound* sound);
     void Play(Sound* sound);
     /// Play a sound with specified frequency.
     /// Play a sound with specified frequency.
@@ -74,7 +74,7 @@ public:
     void SetAutoRemove(bool enable);
     void SetAutoRemove(bool enable);
     /// Set new playback position.
     /// Set new playback position.
     void SetPlayPosition(signed char* pos);
     void SetPlayPosition(signed char* pos);
-    
+
     /// Return sound.
     /// Return sound.
     Sound* GetSound() const { return sound_; }
     Sound* GetSound() const { return sound_; }
     /// Return playback position.
     /// Return playback position.
@@ -95,14 +95,14 @@ public:
     bool GetAutoRemove() const { return autoRemove_; }
     bool GetAutoRemove() const { return autoRemove_; }
     /// Return whether is playing.
     /// Return whether is playing.
     bool IsPlaying() const;
     bool IsPlaying() const;
-    
+
     /// Update the sound source. Perform subclass specific operations. Called by Audio.
     /// Update the sound source. Perform subclass specific operations. Called by Audio.
     virtual void Update(float timeStep);
     virtual void Update(float timeStep);
     /// Mix sound source output to a 32-bit clipping buffer. Called by Audio.
     /// 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);
     void Mix(int* dest, unsigned samples, int mixRate, bool stereo, bool interpolation);
-    
+
     /// Set sound attribute.
     /// Set sound attribute.
-    void SetSoundAttr(ResourceRef value);
+    void SetSoundAttr(const ResourceRef& value);
     /// Set sound position attribute.
     /// Set sound position attribute.
     void SetPositionAttr(int value);
     void SetPositionAttr(int value);
     /// Return sound attribute.
     /// Return sound attribute.
@@ -111,7 +111,7 @@ public:
     void SetPlayingAttr(bool value);
     void SetPlayingAttr(bool value);
     /// Return sound position attribute.
     /// Return sound position attribute.
     int GetPositionAttr() const;
     int GetPositionAttr() const;
-    
+
 protected:
 protected:
     /// Audio subsystem.
     /// Audio subsystem.
     WeakPtr<Audio> audio_;
     WeakPtr<Audio> audio_;
@@ -129,7 +129,7 @@ protected:
     float autoRemoveTimer_;
     float autoRemoveTimer_;
     /// Autoremove flag.
     /// Autoremove flag.
     bool autoRemove_;
     bool autoRemove_;
-    
+
 private:
 private:
     /// Play a sound without locking the audio mutex. Called internally.
     /// Play a sound without locking the audio mutex. Called internally.
     void PlayLockless(Sound* sound);
     void PlayLockless(Sound* sound);
@@ -159,7 +159,7 @@ private:
     void MixZeroVolume(Sound* sound, unsigned samples, int mixRate);
     void MixZeroVolume(Sound* sound, unsigned samples, int mixRate);
     /// Advance playback pointer to simulate audio playback in headless mode.
     /// Advance playback pointer to simulate audio playback in headless mode.
     void MixNull(float timeStep);
     void MixNull(float timeStep);
-    
+
     /// Sound that is being played.
     /// Sound that is being played.
     SharedPtr<Sound> sound_;
     SharedPtr<Sound> sound_;
     /// Sound stream that is being played.
     /// Sound stream that is being played.

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

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

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

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

+ 55 - 56
Source/Engine/Graphics/AnimationController.cpp

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

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

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

+ 52 - 52
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_->SetVertexBuffer(0, vertexBuffer_, MASK_POSITION | MASK_COLOR | MASK_TEXCOORD1 | MASK_TEXCOORD2);
     geometry_->SetIndexBuffer(indexBuffer_);
     geometry_->SetIndexBuffer(indexBuffer_);
-    
+
     batches_.Resize(1);
     batches_.Resize(1);
     batches_[0].geometry_ = geometry_;
     batches_[0].geometry_ = geometry_;
     batches_[0].geometryType_ = GEOM_BILLBOARD;
     batches_[0].geometryType_ = GEOM_BILLBOARD;
@@ -94,9 +94,9 @@ BillboardSet::~BillboardSet()
 void BillboardSet::RegisterObject(Context* context)
 void BillboardSet::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<BillboardSet>(GEOMETRY_CATEGORY);
     context->RegisterFactory<BillboardSet>(GEOMETRY_CATEGORY);
-    
+
     ACCESSOR_ATTRIBUTE(BillboardSet, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
     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);
+    MIXED_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 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, "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, "Sort By Distance", IsSorted, SetSorted, bool, false, AM_DEFAULT);
@@ -107,7 +107,7 @@ void BillboardSet::RegisterObject(Context* context)
     ACCESSOR_ATTRIBUTE(BillboardSet, VAR_FLOAT, "Shadow Distance", GetShadowDistance, SetShadowDistance, 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);
     ACCESSOR_ATTRIBUTE(BillboardSet, VAR_FLOAT, "Animation LOD Bias", GetAnimationLodBias, SetAnimationLodBias, float, 1.0f, AM_DEFAULT);
     COPY_BASE_ATTRIBUTES(BillboardSet, Drawable);
     COPY_BASE_ATTRIBUTES(BillboardSet, Drawable);
-    ACCESSOR_ATTRIBUTE(BillboardSet, VAR_VARIANTVECTOR, "Billboards", GetBillboardsAttr, SetBillboardsAttr, VariantVector, Variant::emptyVariantVector, AM_FILE);
+    MIXED_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);
     REF_ACCESSOR_ATTRIBUTE(BillboardSet, VAR_BUFFER, "Network Billboards", GetNetBillboardsAttr, SetNetBillboardsAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_NET | AM_NOEDIT);
 }
 }
 
 
@@ -123,21 +123,21 @@ void BillboardSet::ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQue
     // Check ray hit distance to AABB before proceeding with billboard-level tests
     // Check ray hit distance to AABB before proceeding with billboard-level tests
     if (query.ray_.HitDistance(GetWorldBoundingBox()) >= query.maxDistance_)
     if (query.ray_.HitDistance(GetWorldBoundingBox()) >= query.maxDistance_)
         return;
         return;
-    
+
     const Matrix3x4& worldTransform = node_->GetWorldTransform();
     const Matrix3x4& worldTransform = node_->GetWorldTransform();
     Matrix3x4 billboardTransform = relative_ ? worldTransform : Matrix3x4::IDENTITY;
     Matrix3x4 billboardTransform = relative_ ? worldTransform : Matrix3x4::IDENTITY;
     Vector3 billboardScale = scaled_ ? worldTransform.Scale() : Vector3::ONE;
     Vector3 billboardScale = scaled_ ? worldTransform.Scale() : Vector3::ONE;
-    
+
     for (unsigned i = 0; i < billboards_.Size(); ++i)
     for (unsigned i = 0; i < billboards_.Size(); ++i)
     {
     {
         if (!billboards_[i].enabled_)
         if (!billboards_[i].enabled_)
             continue;
             continue;
-        
+
         // Approximate the billboards as spheres for raycasting
         // Approximate the billboards as spheres for raycasting
         float size = INV_SQRT_TWO * (billboards_[i].size_.x_ * billboardScale.x_ + billboards_[i].size_.y_ * billboardScale.y_);
         float size = INV_SQRT_TWO * (billboards_[i].size_.x_ * billboardScale.x_ + billboards_[i].size_.y_ * billboardScale.y_);
         Vector3 center = billboardTransform * billboards_[i].position_;
         Vector3 center = billboardTransform * billboards_[i].position_;
         Sphere billboardSphere(center, size);
         Sphere billboardSphere(center, size);
-        
+
         float distance = query.ray_.HitDistance(billboardSphere);
         float distance = query.ray_.HitDistance(billboardSphere);
         if (distance < query.maxDistance_)
         if (distance < query.maxDistance_)
         {
         {
@@ -173,9 +173,9 @@ void BillboardSet::UpdateBatches(const FrameInfo& frame)
             }
             }
         }
         }
     }
     }
-    
+
     distance_ = frame.camera_->GetDistance(GetWorldBoundingBox().Center());
     distance_ = frame.camera_->GetDistance(GetWorldBoundingBox().Center());
-    
+
     // Calculate scaled distance for animation LOD
     // Calculate scaled distance for animation LOD
     float scale = GetWorldBoundingBox().Size().DotProduct(DOT_SCALE);
     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
     // 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_);
         lodDistance_ = frame.camera_->GetLodDistance(distance_, scale, lodBias_);
     else
     else
         lodDistance_ = 0.0f;
         lodDistance_ = 0.0f;
-    
+
     batches_[0].distance_ = distance_;
     batches_[0].distance_ = distance_;
     batches_[0].numWorldTransforms_ = 2;
     batches_[0].numWorldTransforms_ = 2;
     // Billboard positioning
     // Billboard positioning
@@ -197,7 +197,7 @@ void BillboardSet::UpdateGeometry(const FrameInfo& frame)
 {
 {
     if (bufferSizeDirty_ || indexBuffer_->IsDataLost())
     if (bufferSizeDirty_ || indexBuffer_->IsDataLost())
         UpdateBufferSize();
         UpdateBufferSize();
-    
+
     if (bufferDirty_ || vertexBuffer_->IsDataLost())
     if (bufferDirty_ || vertexBuffer_->IsDataLost())
         UpdateVertexBuffer(frame);
         UpdateVertexBuffer(frame);
 }
 }
@@ -223,11 +223,11 @@ void BillboardSet::SetNumBillboards(unsigned num)
         num = 0;
         num = 0;
     if (num > MAX_BILLBOARDS)
     if (num > MAX_BILLBOARDS)
         num = MAX_BILLBOARDS;
         num = MAX_BILLBOARDS;
-    
+
     unsigned oldNum = billboards_.Size();
     unsigned oldNum = billboards_.Size();
-    
+
     billboards_.Resize(num);
     billboards_.Resize(num);
-    
+
     // Set default values to new billboards
     // Set default values to new billboards
     for (unsigned i = oldNum; i < num; ++i)
     for (unsigned i = oldNum; i < num; ++i)
     {
     {
@@ -238,7 +238,7 @@ void BillboardSet::SetNumBillboards(unsigned num)
         billboards_[i].rotation_ = 0.0f;
         billboards_[i].rotation_ = 0.0f;
         billboards_[i].enabled_ = false;
         billboards_[i].enabled_ = false;
     }
     }
-    
+
     bufferSizeDirty_ = true;
     bufferSizeDirty_ = true;
     Commit();
     Commit();
 }
 }
@@ -289,18 +289,18 @@ Billboard* BillboardSet::GetBillboard(unsigned index)
     return index < billboards_.Size() ? &billboards_[index] : (Billboard*)0;
     return index < billboards_.Size() ? &billboards_[index] : (Billboard*)0;
 }
 }
 
 
-void BillboardSet::SetMaterialAttr(ResourceRef value)
+void BillboardSet::SetMaterialAttr(const ResourceRef& value)
 {
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SetMaterial(cache->GetResource<Material>(value.name_));
     SetMaterial(cache->GetResource<Material>(value.name_));
 }
 }
 
 
-void BillboardSet::SetBillboardsAttr(VariantVector value)
+void BillboardSet::SetBillboardsAttr(const VariantVector& value)
 {
 {
     unsigned index = 0;
     unsigned index = 0;
     unsigned numBillboards = index < value.Size() ? value[index++].GetUInt() : 0;
     unsigned numBillboards = index < value.Size() ? value[index++].GetUInt() : 0;
     SetNumBillboards(numBillboards);
     SetNumBillboards(numBillboards);
-    
+
     for (PODVector<Billboard>::Iterator i = billboards_.Begin(); i != billboards_.End() && index < value.Size(); ++i)
     for (PODVector<Billboard>::Iterator i = billboards_.Begin(); i != billboards_.End() && index < value.Size(); ++i)
     {
     {
         i->position_ = value[index++].GetVector3();
         i->position_ = value[index++].GetVector3();
@@ -311,7 +311,7 @@ void BillboardSet::SetBillboardsAttr(VariantVector value)
         i->rotation_ = value[index++].GetFloat();
         i->rotation_ = value[index++].GetFloat();
         i->enabled_ = value[index++].GetBool();
         i->enabled_ = value[index++].GetBool();
     }
     }
-    
+
     Commit();
     Commit();
 }
 }
 
 
@@ -320,7 +320,7 @@ void BillboardSet::SetNetBillboardsAttr(const PODVector<unsigned char>& value)
     MemoryBuffer buf(value);
     MemoryBuffer buf(value);
     unsigned numBillboards = buf.ReadVLE();
     unsigned numBillboards = buf.ReadVLE();
     SetNumBillboards(numBillboards);
     SetNumBillboards(numBillboards);
-    
+
     for (PODVector<Billboard>::Iterator i = billboards_.Begin(); i != billboards_.End(); ++i)
     for (PODVector<Billboard>::Iterator i = billboards_.Begin(); i != billboards_.End(); ++i)
     {
     {
         i->position_ = buf.ReadVector3();
         i->position_ = buf.ReadVector3();
@@ -330,7 +330,7 @@ void BillboardSet::SetNetBillboardsAttr(const PODVector<unsigned char>& value)
         i->rotation_ = buf.ReadFloat();
         i->rotation_ = buf.ReadFloat();
         i->enabled_ = buf.ReadBool();
         i->enabled_ = buf.ReadBool();
     }
     }
-    
+
     Commit();
     Commit();
 }
 }
 
 
@@ -344,7 +344,7 @@ VariantVector BillboardSet::GetBillboardsAttr() const
     VariantVector ret;
     VariantVector ret;
     ret.Reserve(billboards_.Size() * 6 + 1);
     ret.Reserve(billboards_.Size() * 6 + 1);
     ret.Push(billboards_.Size());
     ret.Push(billboards_.Size());
-    
+
     for (PODVector<Billboard>::ConstIterator i = billboards_.Begin(); i != billboards_.End(); ++i)
     for (PODVector<Billboard>::ConstIterator i = billboards_.Begin(); i != billboards_.End(); ++i)
     {
     {
         ret.Push(i->position_);
         ret.Push(i->position_);
@@ -354,7 +354,7 @@ VariantVector BillboardSet::GetBillboardsAttr() const
         ret.Push(i->rotation_);
         ret.Push(i->rotation_);
         ret.Push(i->enabled_);
         ret.Push(i->enabled_);
     }
     }
-    
+
     return ret;
     return ret;
 }
 }
 
 
@@ -362,7 +362,7 @@ const PODVector<unsigned char>& BillboardSet::GetNetBillboardsAttr() const
 {
 {
     attrBuffer_.Clear();
     attrBuffer_.Clear();
     attrBuffer_.WriteVLE(billboards_.Size());
     attrBuffer_.WriteVLE(billboards_.Size());
-    
+
     for (PODVector<Billboard>::ConstIterator i = billboards_.Begin(); i != billboards_.End(); ++i)
     for (PODVector<Billboard>::ConstIterator i = billboards_.Begin(); i != billboards_.End(); ++i)
     {
     {
         attrBuffer_.WriteVector3(i->position_);
         attrBuffer_.WriteVector3(i->position_);
@@ -372,7 +372,7 @@ const PODVector<unsigned char>& BillboardSet::GetNetBillboardsAttr() const
         attrBuffer_.WriteFloat(i->rotation_);
         attrBuffer_.WriteFloat(i->rotation_);
         attrBuffer_.WriteBool(i->enabled_);
         attrBuffer_.WriteBool(i->enabled_);
     }
     }
-    
+
     return attrBuffer_.GetBuffer();
     return attrBuffer_.GetBuffer();
 }
 }
 
 
@@ -388,15 +388,15 @@ void BillboardSet::OnWorldBoundingBoxUpdate()
     {
     {
         if (!billboards_[i].enabled_)
         if (!billboards_[i].enabled_)
             continue;
             continue;
-        
+
         float size = INV_SQRT_TWO * (billboards_[i].size_.x_ * billboardScale.x_ + billboards_[i].size_.y_ * billboardScale.y_);
         float size = INV_SQRT_TWO * (billboards_[i].size_.x_ * billboardScale.x_ + billboards_[i].size_.y_ * billboardScale.y_);
         Vector3 center = billboardTransform * billboards_[i].position_;
         Vector3 center = billboardTransform * billboards_[i].position_;
         Vector3 edge = Vector3::ONE * size;
         Vector3 edge = Vector3::ONE * size;
         worldBox.Merge(BoundingBox(center - edge, center + edge));
         worldBox.Merge(BoundingBox(center - edge, center + edge));
-        
+
         ++enabledBillboards;
         ++enabledBillboards;
     }
     }
-    
+
     // Always merge the node's own position to ensure particle emitter updates continue when the relative mode is switched
     // Always merge the node's own position to ensure particle emitter updates continue when the relative mode is switched
     worldBox.Merge(node_->GetWorldPosition());
     worldBox.Merge(node_->GetWorldPosition());
 
 
@@ -406,34 +406,34 @@ void BillboardSet::OnWorldBoundingBoxUpdate()
 void BillboardSet::UpdateBufferSize()
 void BillboardSet::UpdateBufferSize()
 {
 {
     unsigned numBillboards = billboards_.Size();
     unsigned numBillboards = billboards_.Size();
-    
+
     if (vertexBuffer_->GetVertexCount() != numBillboards * 4)
     if (vertexBuffer_->GetVertexCount() != numBillboards * 4)
         vertexBuffer_->SetSize(numBillboards * 4, MASK_POSITION | MASK_COLOR | MASK_TEXCOORD1 | MASK_TEXCOORD2, true);
         vertexBuffer_->SetSize(numBillboards * 4, MASK_POSITION | MASK_COLOR | MASK_TEXCOORD1 | MASK_TEXCOORD2, true);
     if (indexBuffer_->GetIndexCount() != numBillboards * 6)
     if (indexBuffer_->GetIndexCount() != numBillboards * 6)
         indexBuffer_->SetSize(numBillboards * 6, false);
         indexBuffer_->SetSize(numBillboards * 6, false);
-    
+
     bufferSizeDirty_ = false;
     bufferSizeDirty_ = false;
     bufferDirty_ = true;
     bufferDirty_ = true;
     forceUpdate_ = true;
     forceUpdate_ = true;
-    
+
     if (!numBillboards)
     if (!numBillboards)
         return;
         return;
-    
+
     // Indices do not change for a given billboard capacity
     // Indices do not change for a given billboard capacity
     unsigned short* dest = (unsigned short*)indexBuffer_->Lock(0, numBillboards * 6, true);
     unsigned short* dest = (unsigned short*)indexBuffer_->Lock(0, numBillboards * 6, true);
     if (!dest)
     if (!dest)
         return;
         return;
-    
+
     unsigned vertexIndex = 0;
     unsigned vertexIndex = 0;
     while (numBillboards--)
     while (numBillboards--)
     {
     {
         dest[0] = vertexIndex; dest[1] = vertexIndex + 1; dest[2] = vertexIndex + 2;
         dest[0] = vertexIndex; dest[1] = vertexIndex + 1; dest[2] = vertexIndex + 2;
         dest[3] = vertexIndex + 2; dest[4] = vertexIndex + 3; dest[5] = vertexIndex;
         dest[3] = vertexIndex + 2; dest[4] = vertexIndex + 3; dest[5] = vertexIndex;
-        
+
         dest += 6;
         dest += 6;
         vertexIndex += 4;
         vertexIndex += 4;
     }
     }
-    
+
     indexBuffer_->Unlock();
     indexBuffer_->Unlock();
     indexBuffer_->ClearDataLost();
     indexBuffer_->ClearDataLost();
 }
 }
@@ -453,23 +453,23 @@ void BillboardSet::UpdateVertexBuffer(const FrameInfo& frame)
                 return;
                 return;
         }
         }
     }
     }
-    
+
     unsigned numBillboards = billboards_.Size();
     unsigned numBillboards = billboards_.Size();
     unsigned enabledBillboards = 0;
     unsigned enabledBillboards = 0;
     const Matrix3x4& worldTransform = node_->GetWorldTransform();
     const Matrix3x4& worldTransform = node_->GetWorldTransform();
     Matrix3x4 billboardTransform = relative_ ? worldTransform : Matrix3x4::IDENTITY;
     Matrix3x4 billboardTransform = relative_ ? worldTransform : Matrix3x4::IDENTITY;
     Vector3 billboardScale = scaled_ ? worldTransform.Scale() : Vector3::ONE;
     Vector3 billboardScale = scaled_ ? worldTransform.Scale() : Vector3::ONE;
-    
+
     // First check number of enabled billboards
     // First check number of enabled billboards
     for (unsigned i = 0; i < numBillboards; ++i)
     for (unsigned i = 0; i < numBillboards; ++i)
     {
     {
         if (billboards_[i].enabled_)
         if (billboards_[i].enabled_)
             ++enabledBillboards;
             ++enabledBillboards;
     }
     }
-    
+
     sortedBillboards_.Resize(enabledBillboards);
     sortedBillboards_.Resize(enabledBillboards);
     unsigned index = 0;
     unsigned index = 0;
-    
+
     // Then set initial sort order and distances
     // Then set initial sort order and distances
     for (unsigned i = 0; i < numBillboards; ++i)
     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_);
                 billboard.sortDistance_ = frame.camera_->GetDistanceSquared(billboardTransform * billboards_[i].position_);
         }
         }
     }
     }
-    
+
     batches_[0].geometry_->SetDrawRange(TRIANGLE_LIST, 0, enabledBillboards * 6, false);
     batches_[0].geometry_->SetDrawRange(TRIANGLE_LIST, 0, enabledBillboards * 6, false);
-    
+
     bufferDirty_ = false;
     bufferDirty_ = false;
     forceUpdate_ = false;
     forceUpdate_ = false;
     if (!enabledBillboards)
     if (!enabledBillboards)
         return;
         return;
-    
+
     if (sorted_)
     if (sorted_)
         Sort(sortedBillboards_.Begin(), sortedBillboards_.End(), CompareBillboards);
         Sort(sortedBillboards_.Begin(), sortedBillboards_.End(), CompareBillboards);
-    
+
     float* dest = (float*)vertexBuffer_->Lock(0, enabledBillboards * 4, true);
     float* dest = (float*)vertexBuffer_->Lock(0, enabledBillboards * 4, true);
     if (!dest)
     if (!dest)
         return;
         return;
-    
+
     for (unsigned i = 0; i < enabledBillboards; ++i)
     for (unsigned i = 0; i < enabledBillboards; ++i)
     {
     {
         Billboard& billboard = *sortedBillboards_[i];
         Billboard& billboard = *sortedBillboards_[i];
-        
+
         Vector2 size(billboard.size_.x_ * billboardScale.x_, billboard.size_.y_ * billboardScale.y_);
         Vector2 size(billboard.size_.x_ * billboardScale.x_, billboard.size_.y_ * billboardScale.y_);
         unsigned color = billboard.color_.ToUInt();
         unsigned color = billboard.color_.ToUInt();
-        
+
         float rotationMatrix[2][2];
         float rotationMatrix[2][2];
         rotationMatrix[0][0] = Cos(billboard.rotation_);
         rotationMatrix[0][0] = Cos(billboard.rotation_);
         rotationMatrix[0][1] = Sin(billboard.rotation_);
         rotationMatrix[0][1] = Sin(billboard.rotation_);
         rotationMatrix[1][0] = -rotationMatrix[0][1];
         rotationMatrix[1][0] = -rotationMatrix[0][1];
         rotationMatrix[1][1] = rotationMatrix[0][0];
         rotationMatrix[1][1] = rotationMatrix[0][0];
-        
+
         dest[0] = billboard.position_.x_; dest[1] = billboard.position_.y_; dest[2] = billboard.position_.z_;
         dest[0] = billboard.position_.x_; dest[1] = billboard.position_.y_; dest[2] = billboard.position_.z_;
         ((unsigned&)dest[3]) = color;
         ((unsigned&)dest[3]) = color;
         dest[4] = billboard.uv_.min_.x_; dest[5] = billboard.uv_.min_.y_;
         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[6] = -size.x_ * rotationMatrix[0][0] + size.y_ * rotationMatrix[0][1];
         dest[7] = -size.x_ * rotationMatrix[1][0] + size.y_ * rotationMatrix[1][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_;
         dest[8] = billboard.position_.x_; dest[9] = billboard.position_.y_; dest[10] = billboard.position_.z_;
         ((unsigned&)dest[11]) = color;
         ((unsigned&)dest[11]) = color;
         dest[12] = billboard.uv_.max_.x_; dest[13] = billboard.uv_.min_.y_;
         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[14] = size.x_ * rotationMatrix[0][0] + size.y_ * rotationMatrix[0][1];
         dest[15] = size.x_ * rotationMatrix[1][0] + size.y_ * rotationMatrix[1][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_;
         dest[16] = billboard.position_.x_; dest[17] = billboard.position_.y_; dest[18] = billboard.position_.z_;
         ((unsigned&)dest[19]) = color;
         ((unsigned&)dest[19]) = color;
         dest[20] = billboard.uv_.max_.x_; dest[21] = billboard.uv_.max_.y_;
         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[22] = size.x_ * rotationMatrix[0][0] - size.y_ * rotationMatrix[0][1];
         dest[23] = size.x_ * rotationMatrix[1][0] - size.y_ * rotationMatrix[1][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_;
         dest[24] = billboard.position_.x_; dest[25] = billboard.position_.y_; dest[26] = billboard.position_.z_;
         ((unsigned&)dest[27]) = color;
         ((unsigned&)dest[27]) = color;
         dest[28] = billboard.uv_.min_.x_; dest[29] = billboard.uv_.max_.y_;
         dest[28] = billboard.uv_.min_.x_; dest[29] = billboard.uv_.max_.y_;
@@ -535,7 +535,7 @@ void BillboardSet::UpdateVertexBuffer(const FrameInfo& frame)
 
 
         dest += 32;
         dest += 32;
     }
     }
-    
+
     vertexBuffer_->Unlock();
     vertexBuffer_->Unlock();
     vertexBuffer_->ClearDataLost();
     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
 class URHO3D_API BillboardSet : public Drawable
 {
 {
     OBJECT(BillboardSet);
     OBJECT(BillboardSet);
-    
+
 public:
 public:
     /// Construct.
     /// Construct.
     BillboardSet(Context* context);
     BillboardSet(Context* context);
@@ -67,7 +67,7 @@ public:
     virtual ~BillboardSet();
     virtual ~BillboardSet();
     /// Register object factory.
     /// Register object factory.
     static void RegisterObject(Context* context);
     static void RegisterObject(Context* context);
-    
+
     /// Process octree raycast. May be called from a worker thread.
     /// Process octree raycast. May be called from a worker thread.
     virtual void ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQueryResult>& results);
     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.
     /// 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);
     virtual void UpdateGeometry(const FrameInfo& frame);
     /// Return whether a geometry update is necessary, and if it can happen in a worker thread.
     /// Return whether a geometry update is necessary, and if it can happen in a worker thread.
     virtual UpdateGeometryType GetUpdateGeometryType();
     virtual UpdateGeometryType GetUpdateGeometryType();
-    
+
     /// Set material.
     /// Set material.
     void SetMaterial(Material* material);
     void SetMaterial(Material* material);
     /// Set number of billboards.
     /// Set number of billboards.
@@ -93,7 +93,7 @@ public:
     void SetAnimationLodBias(float bias);
     void SetAnimationLodBias(float bias);
     /// Mark for bounding box and vertex buffer update. Call after modifying the billboards.
     /// Mark for bounding box and vertex buffer update. Call after modifying the billboards.
     void Commit();
     void Commit();
-    
+
     /// Return material.
     /// Return material.
     Material* GetMaterial() const;
     Material* GetMaterial() const;
     /// Return number of billboards.
     /// Return number of billboards.
@@ -112,11 +112,11 @@ public:
     FaceCameraMode GetFaceCameraMode() const { return faceCameraMode_; }
     FaceCameraMode GetFaceCameraMode() const { return faceCameraMode_; }
     /// Return animation LOD bias.
     /// Return animation LOD bias.
     float GetAnimationLodBias() const { return animationLodBias_; }
     float GetAnimationLodBias() const { return animationLodBias_; }
-    
+
     /// Set material attribute.
     /// Set material attribute.
-    void SetMaterialAttr(ResourceRef value);
+    void SetMaterialAttr(const ResourceRef& value);
     /// Set billboards attribute.
     /// Set billboards attribute.
-    void SetBillboardsAttr(VariantVector value);
+    void SetBillboardsAttr(const VariantVector& value);
     /// Set billboards attribute for network replication.
     /// Set billboards attribute for network replication.
     void SetNetBillboardsAttr(const PODVector<unsigned char>& value);
     void SetNetBillboardsAttr(const PODVector<unsigned char>& value);
     /// Return material attribute.
     /// Return material attribute.
@@ -125,13 +125,13 @@ public:
     VariantVector GetBillboardsAttr() const;
     VariantVector GetBillboardsAttr() const;
     /// Return billboards attribute for network replication.
     /// Return billboards attribute for network replication.
     const PODVector<unsigned char>& GetNetBillboardsAttr() const;
     const PODVector<unsigned char>& GetNetBillboardsAttr() const;
-    
+
 protected:
 protected:
     /// Recalculate the world-space bounding box.
     /// Recalculate the world-space bounding box.
     virtual void OnWorldBoundingBoxUpdate();
     virtual void OnWorldBoundingBoxUpdate();
     /// Mark billboard vertex buffer to need an update.
     /// Mark billboard vertex buffer to need an update.
     void MarkPositionsDirty();
     void MarkPositionsDirty();
-    
+
     /// Billboards.
     /// Billboards.
     PODVector<Billboard> billboards_;
     PODVector<Billboard> billboards_;
     /// Coordinate axes on which camera facing is done.
     /// Coordinate axes on which camera facing is done.
@@ -148,13 +148,13 @@ protected:
     bool sorted_;
     bool sorted_;
     /// Billboard rotation mode in relation to the camera.
     /// Billboard rotation mode in relation to the camera.
     FaceCameraMode faceCameraMode_;
     FaceCameraMode faceCameraMode_;
-    
+
 private:
 private:
     /// Resize billboard vertex and index buffers.
     /// Resize billboard vertex and index buffers.
     void UpdateBufferSize();
     void UpdateBufferSize();
     /// Rewrite billboard vertex buffer.
     /// Rewrite billboard vertex buffer.
     void UpdateVertexBuffer(const FrameInfo& frame);
     void UpdateVertexBuffer(const FrameInfo& frame);
-    
+
     /// Geometry.
     /// Geometry.
     SharedPtr<Geometry> geometry_;
     SharedPtr<Geometry> geometry_;
     /// Vertex buffer.
     /// Vertex buffer.

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

@@ -98,8 +98,8 @@ void Camera::RegisterObject(Context* context)
     ATTRIBUTE(Camera, VAR_INT, "View Mask", viewMask_, DEFAULT_VIEWMASK, 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);
     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);
     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);
+    MIXED_ACCESSOR_ATTRIBUTE(Camera, VAR_VECTOR4, "Reflection Plane", GetReflectionPlaneAttr, SetReflectionPlaneAttr, Vector4, Vector4(0.0f, 1.0f, 0.0f, 0.0f), AM_DEFAULT);
+    MIXED_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 Reflection", GetUseReflection, SetUseReflection, bool, false, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Camera, VAR_BOOL, "Use Clipping", GetUseClipping, SetUseClipping, bool, false, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Camera, VAR_BOOL, "Use Clipping", GetUseClipping, SetUseClipping, bool, false, AM_DEFAULT);
 }
 }
@@ -263,7 +263,7 @@ float Camera::GetNearClip() const
 Frustum Camera::GetSplitFrustum(float nearClip, float farClip) const
 Frustum Camera::GetSplitFrustum(float nearClip, float farClip) const
 {
 {
     Frustum ret;
     Frustum ret;
-    
+
     Matrix3x4 worldTransform = GetEffectiveWorldTransform();
     Matrix3x4 worldTransform = GetEffectiveWorldTransform();
     nearClip = Max(nearClip, GetNearClip());
     nearClip = Max(nearClip, GetNearClip());
     farClip = Min(farClip, farClip_);
     farClip = Min(farClip, farClip_);
@@ -365,7 +365,7 @@ const Frustum& Camera::GetFrustum() const
     if (frustumDirty_)
     if (frustumDirty_)
     {
     {
         Matrix3x4 worldTransform = GetEffectiveWorldTransform();
         Matrix3x4 worldTransform = GetEffectiveWorldTransform();
-        
+
         if (!orthographic_)
         if (!orthographic_)
             frustum_.Define(fov_, aspectRatio_, zoom_, GetNearClip(), farClip_, worldTransform);
             frustum_.Define(fov_, aspectRatio_, zoom_, GetNearClip(), farClip_, worldTransform);
         else
         else
@@ -531,39 +531,39 @@ Quaternion Camera::GetFaceCameraRotation(const Vector3& position, const Quaterni
 {
 {
     if (!node_)
     if (!node_)
         return rotation;
         return rotation;
-    
+
     switch (mode)
     switch (mode)
     {
     {
     default:
     default:
         return rotation;
         return rotation;
-        
+
     case FC_ROTATE_XYZ:
     case FC_ROTATE_XYZ:
         return node_->GetWorldRotation();
         return node_->GetWorldRotation();
-        
+
     case FC_ROTATE_Y:
     case FC_ROTATE_Y:
         {
         {
             Vector3 euler = rotation.EulerAngles();
             Vector3 euler = rotation.EulerAngles();
             euler.y_ = node_->GetWorldRotation().EulerAngles().y_;
             euler.y_ = node_->GetWorldRotation().EulerAngles().y_;
             return Quaternion(euler.x_, euler.y_, euler.z_);
             return Quaternion(euler.x_, euler.y_, euler.z_);
         }
         }
-        
+
     case FC_LOOKAT_XYZ:
     case FC_LOOKAT_XYZ:
         {
         {
             Quaternion lookAt;
             Quaternion lookAt;
             lookAt.FromLookRotation(position - node_->GetWorldPosition());
             lookAt.FromLookRotation(position - node_->GetWorldPosition());
             return lookAt;
             return lookAt;
         }
         }
-        
+
     case FC_LOOKAT_Y:
     case FC_LOOKAT_Y:
         {
         {
             // Make the Y-only lookat happen on an XZ plane to make sure there are no unwanted transitions
             // Make the Y-only lookat happen on an XZ plane to make sure there are no unwanted transitions
             // or singularities
             // or singularities
             Vector3 lookAtVec(position - node_->GetWorldPosition());
             Vector3 lookAtVec(position - node_->GetWorldPosition());
             lookAtVec.y_ = 0.0f;
             lookAtVec.y_ = 0.0f;
-            
+
             Quaternion lookAt;
             Quaternion lookAt;
             lookAt.FromLookRotation(lookAtVec);
             lookAt.FromLookRotation(lookAtVec);
-            
+
             Vector3 euler = rotation.EulerAngles();
             Vector3 euler = rotation.EulerAngles();
             euler.y_ = lookAt.EulerAngles().y_;
             euler.y_ = lookAt.EulerAngles().y_;
             return Quaternion(euler.x_, euler.y_, euler.z_);
             return Quaternion(euler.x_, euler.y_, euler.z_);
@@ -590,7 +590,7 @@ const Matrix3x4& Camera::GetView() const
         view_ = GetEffectiveWorldTransform().Inverse();
         view_ = GetEffectiveWorldTransform().Inverse();
         viewDirty_ = false;
         viewDirty_ = false;
     }
     }
-    
+
     return view_;
     return view_;
 }
 }
 
 
@@ -602,12 +602,12 @@ void Camera::SetAspectRatioInternal(float aspectRatio)
     MarkNetworkUpdate();
     MarkNetworkUpdate();
 }
 }
 
 
-void Camera::SetReflectionPlaneAttr(Vector4 value)
+void Camera::SetReflectionPlaneAttr(const Vector4& value)
 {
 {
     SetReflectionPlane(Plane(value));
     SetReflectionPlane(Plane(value));
 }
 }
 
 
-void Camera::SetClipPlaneAttr(Vector4 value)
+void Camera::SetClipPlaneAttr(const Vector4& value)
 {
 {
     SetClipPlane(Plane(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
 class URHO3D_API Camera : public Component
 {
 {
     OBJECT(Camera);
     OBJECT(Camera);
-    
+
 public:
 public:
     /// Construct.
     /// Construct.
     Camera(Context* context);
     Camera(Context* context);
@@ -52,10 +52,10 @@ public:
     virtual ~Camera();
     virtual ~Camera();
     /// Register object factory.
     /// Register object factory.
     static void RegisterObject(Context* context);
     static void RegisterObject(Context* context);
-    
+
     /// Visualize the component as debug geometry.
     /// Visualize the component as debug geometry.
     virtual void DrawDebugGeometry(DebugRenderer* debug, bool depthTest);
     virtual void DrawDebugGeometry(DebugRenderer* debug, bool depthTest);
-    
+
     /// Set near clip distance.
     /// Set near clip distance.
     void SetNearClip(float nearClip);
     void SetNearClip(float nearClip);
     /// Set far clip distance.
     /// Set far clip distance.
@@ -94,7 +94,7 @@ public:
     void SetClipPlane(const Plane& plane);
     void SetClipPlane(const Plane& plane);
     /// Set vertical flipping mode. Called internally by View to resolve OpenGL / Direct3D9 rendertarget sampling differences.
     /// Set vertical flipping mode. Called internally by View to resolve OpenGL / Direct3D9 rendertarget sampling differences.
     void SetFlipVertical(bool enable);
     void SetFlipVertical(bool enable);
-    
+
     /// Return far clip distance.
     /// Return far clip distance.
     float GetFarClip() const { return farClip_; }
     float GetFarClip() const { return farClip_; }
     /// Return near clip distance.
     /// Return near clip distance.
@@ -102,7 +102,7 @@ public:
     /// Return vertical field of view in degrees.
     /// Return vertical field of view in degrees.
     float GetFov() const { return fov_; }
     float GetFov() const { return fov_; }
     /// Return orthographic mode size.
     /// Return orthographic mode size.
-    float GetOrthoSize() const { return orthoSize_; } 
+    float GetOrthoSize() const { return orthoSize_; }
     /// Return aspect ratio.
     /// Return aspect ratio.
     float GetAspectRatio() const { return aspectRatio_; }
     float GetAspectRatio() const { return aspectRatio_; }
     /// Return zoom.
     /// Return zoom.
@@ -169,24 +169,24 @@ public:
     Matrix3x4 GetEffectiveWorldTransform() const;
     Matrix3x4 GetEffectiveWorldTransform() const;
     /// Return if projection parameters are valid for rendering and raycasting.
     /// Return if projection parameters are valid for rendering and raycasting.
     bool IsProjectionValid() const;
     bool IsProjectionValid() const;
-    
+
     /// Set aspect ratio without disabling the "auto aspect ratio" mode. Called internally by View.
     /// Set aspect ratio without disabling the "auto aspect ratio" mode. Called internally by View.
     void SetAspectRatioInternal(float aspectRatio);
     void SetAspectRatioInternal(float aspectRatio);
     /// Set reflection plane attribute.
     /// Set reflection plane attribute.
-    void SetReflectionPlaneAttr(Vector4 value);
+    void SetReflectionPlaneAttr(const Vector4& value);
     /// Return reflection plane attribute.
     /// Return reflection plane attribute.
     Vector4 GetReflectionPlaneAttr() const;
     Vector4 GetReflectionPlaneAttr() const;
     /// Set clipping plane attribute.
     /// Set clipping plane attribute.
-    void SetClipPlaneAttr(Vector4 value);
+    void SetClipPlaneAttr(const Vector4& value);
     /// Return clipping plane attribute.
     /// Return clipping plane attribute.
     Vector4 GetClipPlaneAttr() const;
     Vector4 GetClipPlaneAttr() const;
-    
+
 protected:
 protected:
     /// Handle node being assigned.
     /// Handle node being assigned.
     virtual void OnNodeSet(Node* node);
     virtual void OnNodeSet(Node* node);
     /// Handle node transform being dirtied.
     /// Handle node transform being dirtied.
     virtual void OnMarkedDirty(Node* node);
     virtual void OnMarkedDirty(Node* node);
-    
+
 private:
 private:
     /// Cached view matrix.
     /// Cached view matrix.
     mutable Matrix3x4 view_;
     mutable Matrix3x4 view_;

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

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

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

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

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

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

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

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

+ 9 - 9
Source/Engine/Graphics/Light.cpp

@@ -123,8 +123,8 @@ void Light::RegisterObject(Context* context)
     ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Range", GetRange, SetRange, float, DEFAULT_RANGE, 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 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_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);
+    MIXED_ACCESSOR_ATTRIBUTE(Light, VAR_RESOURCEREF, "Attenuation Texture", GetRampTextureAttr, SetRampTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_DEFAULT);
+    MIXED_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);
     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, "Cast Shadows", castShadows_, false, AM_DEFAULT);
     ATTRIBUTE(Light, VAR_BOOL, "Per Vertex", perVertex_, false, AM_DEFAULT);
     ATTRIBUTE(Light, VAR_BOOL, "Per Vertex", perVertex_, false, AM_DEFAULT);
@@ -230,7 +230,7 @@ void Light::UpdateBatches(const FrameInfo& frame)
 void Light::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
 void Light::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
 {
 {
     Color color = GetEffectiveColor();
     Color color = GetEffectiveColor();
-    
+
     if (debug && IsEnabledEffective())
     if (debug && IsEnabledEffective())
     {
     {
         switch (lightType_)
         switch (lightType_)
@@ -390,7 +390,7 @@ Frustum Light::GetFrustum() const
 int Light::GetNumShadowSplits() const
 int Light::GetNumShadowSplits() const
 {
 {
     int ret = 1;
     int ret = 1;
-    
+
     if (shadowCascade_.splits_[1] > shadowCascade_.splits_[0])
     if (shadowCascade_.splits_[1] > shadowCascade_.splits_[0])
     {
     {
         ++ret;
         ++ret;
@@ -401,7 +401,7 @@ int Light::GetNumShadowSplits() const
                 ++ret;
                 ++ret;
         }
         }
     }
     }
-    
+
     ret = Min(ret, MAX_CASCADE_SPLITS);
     ret = Min(ret, MAX_CASCADE_SPLITS);
     // Shader Model 2 can only support 3 splits max. due to pixel shader instruction count limits
     // Shader Model 2 can only support 3 splits max. due to pixel shader instruction count limits
     if (ret == 4)
     if (ret == 4)
@@ -410,7 +410,7 @@ int Light::GetNumShadowSplits() const
         if (graphics && !graphics->GetSM3Support())
         if (graphics && !graphics->GetSM3Support())
             --ret;
             --ret;
     }
     }
-    
+
     return ret;
     return ret;
 }
 }
 
 
@@ -441,7 +441,7 @@ const Matrix3x4& Light::GetVolumeTransform(Camera* camera)
 {
 {
     if (!node_)
     if (!node_)
         return Matrix3x4::IDENTITY;
         return Matrix3x4::IDENTITY;
-    
+
     switch (lightType_)
     switch (lightType_)
     {
     {
     case LIGHT_DIRECTIONAL:
     case LIGHT_DIRECTIONAL:
@@ -464,13 +464,13 @@ const Matrix3x4& Light::GetVolumeTransform(Camera* camera)
     return volumeTransform_;
     return volumeTransform_;
 }
 }
 
 
-void Light::SetRampTextureAttr(ResourceRef value)
+void Light::SetRampTextureAttr(const ResourceRef& value)
 {
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     rampTexture_ = static_cast<Texture*>(cache->GetResource(value.type_, value.name_));
     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>();
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     shapeTexture_ = static_cast<Texture*>(cache->GetResource(value.type_, value.name_));
     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()
     BiasParameters()
     {
     {
     }
     }
-    
+
     /// Construct with initial values.
     /// Construct with initial values.
     BiasParameters(float constantBias, float slopeScaledBias) :
     BiasParameters(float constantBias, float slopeScaledBias) :
         constantBias_(constantBias),
         constantBias_(constantBias),
         slopeScaledBias_(slopeScaledBias)
         slopeScaledBias_(slopeScaledBias)
     {
     {
     }
     }
-    
+
     /// Validate parameters.
     /// Validate parameters.
     void Validate();
     void Validate();
-    
+
     /// Constant bias.
     /// Constant bias.
     float constantBias_;
     float constantBias_;
     /// Slope scaled bias.
     /// Slope scaled bias.
@@ -81,7 +81,7 @@ struct URHO3D_API CascadeParameters
     CascadeParameters()
     CascadeParameters()
     {
     {
     }
     }
-    
+
     /// Construct with initial values.
     /// Construct with initial values.
     CascadeParameters(float split1, float split2, float split3, float split4, float fadeStart, float biasAutoAdjust = 1.0f) :
     CascadeParameters(float split1, float split2, float split3, float split4, float fadeStart, float biasAutoAdjust = 1.0f) :
         fadeStart_(fadeStart),
         fadeStart_(fadeStart),
@@ -92,20 +92,20 @@ struct URHO3D_API CascadeParameters
         splits_[2] = split3;
         splits_[2] = split3;
         splits_[3] = split4;
         splits_[3] = split4;
     }
     }
-    
+
     /// Validate parameters.
     /// Validate parameters.
     void Validate();
     void Validate();
-    
+
     /// Return shadow maximum range.
     /// Return shadow maximum range.
     float GetShadowRange() const
     float GetShadowRange() const
     {
     {
         float ret = 0.0f;
         float ret = 0.0f;
         for (unsigned i = 0; i < MAX_CASCADE_SPLITS; ++i)
         for (unsigned i = 0; i < MAX_CASCADE_SPLITS; ++i)
             ret = Max(ret, splits_[i]);
             ret = Max(ret, splits_[i]);
-        
+
         return ret;
         return ret;
     }
     }
-    
+
     /// Far clip values of the splits.
     /// Far clip values of the splits.
     float splits_[4];
     float splits_[4];
     /// The point relative to the total shadow range where shadow fade begins (0.0 - 1.0)
     /// 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()
     FocusParameters()
     {
     {
     }
     }
-    
+
     /// Construct with initial values.
     /// Construct with initial values.
     FocusParameters(bool focus, bool nonUniform, bool autoSize, float quantize, float minView) :
     FocusParameters(bool focus, bool nonUniform, bool autoSize, float quantize, float minView) :
         focus_(focus),
         focus_(focus),
@@ -131,10 +131,10 @@ struct URHO3D_API FocusParameters
         minView_(minView)
         minView_(minView)
     {
     {
     }
     }
-    
+
     /// Validate parameters.
     /// Validate parameters.
     void Validate();
     void Validate();
-    
+
     /// Focus flag.
     /// Focus flag.
     bool focus_;
     bool focus_;
     /// Non-uniform focusing flag.
     /// Non-uniform focusing flag.
@@ -151,7 +151,7 @@ struct URHO3D_API FocusParameters
 class URHO3D_API Light : public Drawable
 class URHO3D_API Light : public Drawable
 {
 {
     OBJECT(Light);
     OBJECT(Light);
-    
+
 public:
 public:
     /// Construct.
     /// Construct.
     Light(Context* context);
     Light(Context* context);
@@ -159,7 +159,7 @@ public:
     virtual ~Light();
     virtual ~Light();
     /// Register object factory. Drawable must be registered first.
     /// Register object factory. Drawable must be registered first.
     static void RegisterObject(Context* context);
     static void RegisterObject(Context* context);
-    
+
     /// Handle attribute change.
     /// Handle attribute change.
     virtual void OnSetAttribute(const AttributeInfo& attr, const Variant& src);
     virtual void OnSetAttribute(const AttributeInfo& attr, const Variant& src);
     /// Process octree raycast. May be called from a worker thread.
     /// Process octree raycast. May be called from a worker thread.
@@ -168,7 +168,7 @@ public:
     virtual void UpdateBatches(const FrameInfo& frame);
     virtual void UpdateBatches(const FrameInfo& frame);
     /// Visualize the component as debug geometry.
     /// Visualize the component as debug geometry.
     virtual void DrawDebugGeometry(DebugRenderer* debug, bool depthTest);
     virtual void DrawDebugGeometry(DebugRenderer* debug, bool depthTest);
-    
+
     /// Set light type.
     /// Set light type.
     void SetLightType(LightType type);
     void SetLightType(LightType type);
     /// Set vertex lighting mode.
     /// Set vertex lighting mode.
@@ -205,7 +205,7 @@ public:
     void SetRampTexture(Texture* texture);
     void SetRampTexture(Texture* texture);
     /// Set spotlight attenuation texture.
     /// Set spotlight attenuation texture.
     void SetShapeTexture(Texture* texture);
     void SetShapeTexture(Texture* texture);
-    
+
     /// Return light type.
     /// Return light type.
     LightType GetLightType() const { return lightType_; }
     LightType GetLightType() const { return lightType_; }
     /// Return vertex lighting mode.
     /// Return vertex lighting mode.
@@ -252,7 +252,7 @@ public:
     int GetNumShadowSplits() const;
     int GetNumShadowSplits() const;
     /// Return whether light has negative (darkening) color.
     /// Return whether light has negative (darkening) color.
     bool IsNegative() const { return GetEffectiveColor().SumRGB() < 0.0f; }
     bool IsNegative() const { return GetEffectiveColor().SumRGB() < 0.0f; }
-    
+
     /// Set sort value based on intensity and view distance.
     /// Set sort value based on intensity and view distance.
     void SetIntensitySortValue(float distance);
     void SetIntensitySortValue(float distance);
     /// Set sort value based on overall intensity over a bounding box.
     /// Set sort value based on overall intensity over a bounding box.
@@ -267,20 +267,20 @@ public:
     LightBatchQueue* GetLightQueue() const { return lightQueue_; }
     LightBatchQueue* GetLightQueue() const { return lightQueue_; }
     /// Return a divisor value based on intensity for calculating the sort value.
     /// 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; }
     float GetIntensityDivisor(float attenuation = 1.0f) const { return Max(GetEffectiveColor().SumRGB(), 0.0f) * attenuation + M_EPSILON; }
-    
+
     /// Set ramp texture attribute.
     /// Set ramp texture attribute.
-    void SetRampTextureAttr(ResourceRef value);
+    void SetRampTextureAttr(const ResourceRef& value);
     /// Set shape texture attribute.
     /// Set shape texture attribute.
-    void SetShapeTextureAttr(ResourceRef value);
+    void SetShapeTextureAttr(const ResourceRef& value);
     /// Return ramp texture attribute.
     /// Return ramp texture attribute.
     ResourceRef GetRampTextureAttr() const;
     ResourceRef GetRampTextureAttr() const;
     /// Return shape texture attribute.
     /// Return shape texture attribute.
     ResourceRef GetShapeTextureAttr() const;
     ResourceRef GetShapeTextureAttr() const;
-    
+
 protected:
 protected:
     /// Recalculate the world-space bounding box.
     /// Recalculate the world-space bounding box.
     virtual void OnWorldBoundingBoxUpdate();
     virtual void OnWorldBoundingBoxUpdate();
-    
+
 private:
 private:
     /// Light type.
     /// Light type.
     LightType lightType_;
     LightType lightType_;

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

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

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

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

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

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

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

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

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

@@ -95,8 +95,8 @@ void Terrain::RegisterObject(Context* context)
     context->RegisterFactory<Terrain>(GEOMETRY_CATEGORY);
     context->RegisterFactory<Terrain>(GEOMETRY_CATEGORY);
 
 
     ACCESSOR_ATTRIBUTE(Terrain, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
     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);
+    MIXED_ACCESSOR_ATTRIBUTE(Terrain, VAR_RESOURCEREF, "Height Map", GetHeightMapAttr, SetHeightMapAttr, ResourceRef, ResourceRef(Image::GetTypeStatic()), AM_DEFAULT);
+    MIXED_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);
     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);
     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);
     ATTRIBUTE(Terrain, VAR_BOOL, "Smooth Height Map", smoothing_, false, AM_DEFAULT);
@@ -427,13 +427,13 @@ IntVector2 Terrain::WorldToHeightMap(const Vector3& worldPosition) const
 {
 {
     if (!node_)
     if (!node_)
         return IntVector2::ZERO;
         return IntVector2::ZERO;
-    
+
     Vector3 position = node_->GetWorldTransform().Inverse() * worldPosition;
     Vector3 position = node_->GetWorldTransform().Inverse() * worldPosition;
     int xPos = (int)((position.x_ - patchWorldOrigin_.x_) / spacing_.x_);
     int xPos = (int)((position.x_ - patchWorldOrigin_.x_) / spacing_.x_);
     int zPos = (int)((position.z_ - patchWorldOrigin_.y_) / spacing_.z_);
     int zPos = (int)((position.z_ - patchWorldOrigin_.y_) / spacing_.z_);
     Clamp(xPos, 0, numVertices_.x_);
     Clamp(xPos, 0, numVertices_.x_);
     Clamp(zPos, 0, numVertices_.y_);
     Clamp(zPos, 0, numVertices_.y_);
-    
+
     return IntVector2(xPos, numVertices_.y_ - zPos);
     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);
         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>();
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SetMaterial(cache->GetResource<Material>(value.name_));
     SetMaterial(cache->GetResource<Material>(value.name_));
 }
 }
 
 
-void Terrain::SetHeightMapAttr(ResourceRef value)
+void Terrain::SetHeightMapAttr(const ResourceRef& value)
 {
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     Image* image = cache->GetResource<Image>(value.name_);
     Image* image = cache->GetResource<Image>(value.name_);
@@ -590,7 +590,7 @@ ResourceRef Terrain::GetHeightMapAttr() const
 void Terrain::CreateGeometry()
 void Terrain::CreateGeometry()
 {
 {
     recreateTerrain_ = false;
     recreateTerrain_ = false;
-    
+
     if (!node_)
     if (!node_)
         return;
         return;
 
 
@@ -610,7 +610,7 @@ void Terrain::CreateGeometry()
     // Determine total terrain size
     // Determine total terrain size
     patchWorldSize_ = Vector2(spacing_.x_ * (float)patchSize_, spacing_.z_ * (float)patchSize_);
     patchWorldSize_ = Vector2(spacing_.x_ * (float)patchSize_, spacing_.z_ * (float)patchSize_);
     bool updateAll = false;
     bool updateAll = false;
-    
+
     if (heightMap_)
     if (heightMap_)
     {
     {
         numPatches_ = IntVector2((heightMap_->GetWidth() - 1) / patchSize_, (heightMap_->GetHeight() - 1) / patchSize_);
         numPatches_ = IntVector2((heightMap_->GetWidth() - 1) / patchSize_, (heightMap_->GetHeight() - 1) / patchSize_);
@@ -620,11 +620,11 @@ void Terrain::CreateGeometry()
         if (numVertices_ != lastNumVertices_ || lastSpacing_ != spacing_ || patchSize_ != lastPatchSize_ )
         if (numVertices_ != lastNumVertices_ || lastSpacing_ != spacing_ || patchSize_ != lastPatchSize_ )
             updateAll = true;
             updateAll = true;
         unsigned newDataSize = numVertices_.x_ * numVertices_.y_;
         unsigned newDataSize = numVertices_.x_ * numVertices_.y_;
-        
+
         // Create new height data if terrain size changed
         // Create new height data if terrain size changed
         if (!heightData_ || updateAll)
         if (!heightData_ || updateAll)
             heightData_ = new float[newDataSize];
             heightData_ = new float[newDataSize];
-        
+
         // Ensure that the source (unsmoothed) data exists if smoothing is active
         // Ensure that the source (unsmoothed) data exists if smoothing is active
         if (smoothing_ && (!sourceHeightData_ || updateAll))
         if (smoothing_ && (!sourceHeightData_ || updateAll))
         {
         {
@@ -646,12 +646,12 @@ void Terrain::CreateGeometry()
     lastNumVertices_ = numVertices_;
     lastNumVertices_ = numVertices_;
     lastPatchSize_ = patchSize_;
     lastPatchSize_ = patchSize_;
     lastSpacing_ = spacing_;
     lastSpacing_ = spacing_;
-    
+
     // Remove old patch nodes which are not needed
     // Remove old patch nodes which are not needed
     if (updateAll)
     if (updateAll)
     {
     {
         PROFILE(RemoveOldPatches);
         PROFILE(RemoveOldPatches);
-        
+
         PODVector<Node*> oldPatchNodes;
         PODVector<Node*> oldPatchNodes;
         node_->GetChildrenWithComponent<TerrainPatch>(oldPatchNodes);
         node_->GetChildrenWithComponent<TerrainPatch>(oldPatchNodes);
         for (PODVector<Node*>::Iterator i = oldPatchNodes.Begin(); i != oldPatchNodes.End(); ++i)
         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_);
     PODVector<bool> dirtyPatches(numPatches_.x_ * numPatches_.y_);
     for (unsigned i = 0; i < dirtyPatches.Size(); ++i)
     for (unsigned i = 0; i < dirtyPatches.Size(); ++i)
         dirtyPatches[i] = updateAll;
         dirtyPatches[i] = updateAll;
-    
+
     patches_.Clear();
     patches_.Clear();
 
 
     if (heightMap_)
     if (heightMap_)
@@ -689,13 +689,13 @@ void Terrain::CreateGeometry()
         if (imgComps == 1)
         if (imgComps == 1)
         {
         {
             PROFILE(CopyHeightData);
             PROFILE(CopyHeightData);
-            
+
             for (int z = 0; z < numVertices_.y_; ++z)
             for (int z = 0; z < numVertices_.y_; ++z)
             {
             {
                 for (int x = 0; x < numVertices_.x_; ++x)
                 for (int x = 0; x < numVertices_.x_; ++x)
                 {
                 {
                     float newHeight = (float)src[imgRow * (numVertices_.y_ - 1 - z) + x] * spacing_.y_;
                     float newHeight = (float)src[imgRow * (numVertices_.y_ - 1 - z) + x] * spacing_.y_;
-                    
+
                     if (updateAll)
                     if (updateAll)
                         *dest = newHeight;
                         *dest = newHeight;
                     else
                     else
@@ -710,11 +710,11 @@ void Terrain::CreateGeometry()
                                     for (int x1 = x - 1; x1 <= z + 1; ++x1)
                                     for (int x1 = x - 1; x1 <= z + 1; ++x1)
                                         MarkPatchesDirty(dirtyPatches, x1, z1);
                                         MarkPatchesDirty(dirtyPatches, x1, z1);
                             }
                             }
-                            
+
                             *dest = newHeight;
                             *dest = newHeight;
                         }
                         }
                     }
                     }
-                    
+
                     ++dest;
                     ++dest;
                 }
                 }
             }
             }
@@ -722,7 +722,7 @@ void Terrain::CreateGeometry()
         else
         else
         {
         {
             PROFILE(CopyHeightData);
             PROFILE(CopyHeightData);
-            
+
             // If more than 1 component, use the green channel for more accuracy
             // If more than 1 component, use the green channel for more accuracy
             for (int z = 0; z < numVertices_.y_; ++z)
             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 *
                     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_;
                         (numVertices_.y_ - 1 - z) + imgComps * x + 1] / 256.0f) * spacing_.y_;
-                        
+
                     if (updateAll)
                     if (updateAll)
                         *dest = newHeight;
                         *dest = newHeight;
                     else
                     else
@@ -745,11 +745,11 @@ void Terrain::CreateGeometry()
                                     for (int x1 = x - 1; x1 <= z + 1; ++x1)
                                     for (int x1 = x - 1; x1 <= z + 1; ++x1)
                                         MarkPatchesDirty(dirtyPatches, x1, z1);
                                         MarkPatchesDirty(dirtyPatches, x1, z1);
                             }
                             }
-                            
+
                             *dest = newHeight;
                             *dest = newHeight;
                         }
                         }
                     }
                     }
-                    
+
                     ++dest;
                     ++dest;
                 }
                 }
             }
             }
@@ -761,7 +761,7 @@ void Terrain::CreateGeometry()
 
 
         {
         {
             PROFILE(CreatePatches);
             PROFILE(CreatePatches);
-            
+
             // Create patches and set node transforms
             // Create patches and set node transforms
             for (int z = 0; z < numPatches_.y_; ++z)
             for (int z = 0; z < numPatches_.y_; ++z)
             {
             {
@@ -769,7 +769,7 @@ void Terrain::CreateGeometry()
                 {
                 {
                     String nodeName = "Patch_" + String(x) + "_" + String(z);
                     String nodeName = "Patch_" + String(x) + "_" + String(z);
                     Node* patchNode = node_->GetChild(nodeName);
                     Node* patchNode = node_->GetChild(nodeName);
-                    
+
                     if (!patchNode)
                     if (!patchNode)
                     {
                     {
                         // Create the patch scene node as local and temporary so that it is not unnecessarily serialized to either
                         // 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 = node_->CreateChild(nodeName, LOCAL);
                         patchNode->SetTemporary(true);
                         patchNode->SetTemporary(true);
                     }
                     }
-                    
+
                     patchNode->SetPosition(Vector3(patchWorldOrigin_.x_ + (float)x * patchWorldSize_.x_, 0.0f, patchWorldOrigin_.y_ +
                     patchNode->SetPosition(Vector3(patchWorldOrigin_.x_ + (float)x * patchWorldSize_.x_, 0.0f, patchWorldOrigin_.y_ +
                         (float)z * patchWorldSize_.y_));
                         (float)z * patchWorldSize_.y_));
 
 
@@ -808,7 +808,7 @@ void Terrain::CreateGeometry()
                 }
                 }
             }
             }
         }
         }
-        
+
         // Create the shared index data
         // Create the shared index data
         if (updateAll)
         if (updateAll)
             CreateIndexData();
             CreateIndexData();
@@ -817,7 +817,7 @@ void Terrain::CreateGeometry()
         if (smoothing_)
         if (smoothing_)
         {
         {
             PROFILE(UpdateSmoothing);
             PROFILE(UpdateSmoothing);
-            
+
             for (unsigned i = 0; i < patches_.Size(); ++i)
             for (unsigned i = 0; i < patches_.Size(); ++i)
             {
             {
                 if (dirtyPatches[i])
                 if (dirtyPatches[i])
@@ -828,7 +828,7 @@ void Terrain::CreateGeometry()
                     int endX = startX + patchSize_;
                     int endX = startX + patchSize_;
                     int startZ = coords.y_ * patchSize_;
                     int startZ = coords.y_ * patchSize_;
                     int endZ = startZ + patchSize_;
                     int endZ = startZ + patchSize_;
-                    
+
                     for (int z = startZ; z <= endZ; ++z)
                     for (int z = startZ; z <= endZ; ++z)
                     {
                     {
                         for (int x = startX; x <= endX; ++x)
                         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) * 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)
                                 GetSourceHeight(x - 1, z + 1) + GetSourceHeight(x, z + 1) * 2.0f + GetSourceHeight(x + 1, z + 1)
                             ) / 16.0f;
                             ) / 16.0f;
-                            
+
                             heightData_[z * numVertices_.x_ + x] = smoothedHeight;
                             heightData_[z * numVertices_.x_ + x] = smoothedHeight;
                         }
                         }
                     }
                     }
                 }
                 }
             }
             }
         }
         }
-        
+
         for (unsigned i = 0; i < patches_.Size(); ++i)
         for (unsigned i = 0; i < patches_.Size(); ++i)
         {
         {
             TerrainPatch* patch = patches_[i];
             TerrainPatch* patch = patches_[i];
-            
+
             if (dirtyPatches[i])
             if (dirtyPatches[i])
             {
             {
                 CreatePatchGeometry(patch);
                 CreatePatchGeometry(patch);
                 CalculateLodErrors(patch);
                 CalculateLodErrors(patch);
             }
             }
-            
+
             SetNeighbors(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:
     /* 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
        north, south, west, east, or any combination of them, requiring 16 different versions of each LOD level's index data
-    
+
        Normal edge:     Stitched edge:
        Normal edge:     Stitched edge:
        +----+----+      +---------+
        +----+----+      +---------+
        |\   |\   |      |\       /|
        |\   |\   |      |\       /|
@@ -1181,7 +1181,7 @@ void Terrain::MarkPatchesDirty(PODVector<bool>& dirtyPatches, int x, int z)
 {
 {
     x = Clamp(x, 0, numVertices_.x_);
     x = Clamp(x, 0, numVertices_.x_);
     z = Clamp(z, 0, numVertices_.y_);
     z = Clamp(z, 0, numVertices_.y_);
-    
+
     // A point on the heightmap can potentially belong to multiple patches; dirty all that are applicable
     // A point on the heightmap can potentially belong to multiple patches; dirty all that are applicable
     int pZ = z / patchSize_;
     int pZ = z / patchSize_;
     int vZ = 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.
     /// Update patch based on LOD and neighbor LOD.
     void UpdatePatchLod(TerrainPatch* patch);
     void UpdatePatchLod(TerrainPatch* patch);
     /// Set heightmap attribute.
     /// Set heightmap attribute.
-    void SetHeightMapAttr(ResourceRef value);
+    void SetHeightMapAttr(const ResourceRef& value);
     /// Set material attribute.
     /// Set material attribute.
-    void SetMaterialAttr(ResourceRef value);
+    void SetMaterialAttr(const ResourceRef& value);
     /// Set patch size attribute.
     /// Set patch size attribute.
     void SetPatchSizeAttr(int value);
     void SetPatchSizeAttr(int value);
     /// Return heightmap attribute.
     /// Return heightmap attribute.
@@ -177,7 +177,7 @@ private:
     void HandleHeightMapReloadFinished(StringHash eventType, VariantMap& eventData);
     void HandleHeightMapReloadFinished(StringHash eventType, VariantMap& eventData);
     /// Mark patch(es) dirty based on location. Used when checking the heightmap image for changes.
     /// Mark patch(es) dirty based on location. Used when checking the heightmap image for changes.
     void MarkPatchesDirty(PODVector<bool>& dirtyPatches, int x, int z);
     void MarkPatchesDirty(PODVector<bool>& dirtyPatches, int x, int z);
-    
+
     /// Shared index buffer.
     /// Shared index buffer.
     SharedPtr<IndexBuffer> indexBuffer_;
     SharedPtr<IndexBuffer> indexBuffer_;
     /// Heightmap image.
     /// Heightmap image.

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

@@ -84,7 +84,7 @@ void Zone::RegisterObject(Context* context)
     ATTRIBUTE(Zone, VAR_BOOL, "Override Mode", override_, 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_BOOL, "Ambient Gradient", ambientGradient_, false, AM_DEFAULT);
     ATTRIBUTE(Zone, VAR_INT, "Priority", priority_, 0, 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);
+    MIXED_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, "Light Mask", lightMask_, DEFAULT_LIGHTMASK, AM_DEFAULT);
     ATTRIBUTE(Zone, VAR_INT, "Shadow Mask", shadowMask_, DEFAULT_SHADOWMASK, 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(Zone, VAR_INT, "Zone Mask", GetZoneMask, SetZoneMask, unsigned, DEFAULT_ZONEMASK, AM_DEFAULT);
@@ -225,7 +225,7 @@ bool Zone::IsInside(const Vector3& point) const
     return boundingBox_.IsInside(localPoint) != OUTSIDE;
     return boundingBox_.IsInside(localPoint) != OUTSIDE;
 }
 }
 
 
-void Zone::SetZoneTextureAttr(ResourceRef value)
+void Zone::SetZoneTextureAttr(const ResourceRef& value)
 {
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     zoneTexture_ = static_cast<Texture*>(cache->GetResource(value.type_, value.name_));
     zoneTexture_ = static_cast<Texture*>(cache->GetResource(value.type_, value.name_));
@@ -247,10 +247,10 @@ void Zone::OnMarkedDirty(Node* node)
     }
     }
 
 
     Drawable::OnMarkedDirty(node);
     Drawable::OnMarkedDirty(node);
-    
+
     // Clear zone reference from all drawables inside the bounding box, and mark gradient dirty in neighbor zones
     // Clear zone reference from all drawables inside the bounding box, and mark gradient dirty in neighbor zones
     ClearDrawablesZone();
     ClearDrawablesZone();
-    
+
     inverseWorldDirty_ = true;
     inverseWorldDirty_ = true;
 }
 }
 
 

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

@@ -33,7 +33,7 @@ namespace Urho3D
 class URHO3D_API Zone : public Drawable
 class URHO3D_API Zone : public Drawable
 {
 {
     OBJECT(Zone);
     OBJECT(Zone);
-    
+
 public:
 public:
     /// Construct.
     /// Construct.
     Zone(Context* context);
     Zone(Context* context);
@@ -41,12 +41,12 @@ public:
     virtual ~Zone();
     virtual ~Zone();
     /// Register object factory. Drawable must be registered first.
     /// Register object factory. Drawable must be registered first.
     static void RegisterObject(Context* context);
     static void RegisterObject(Context* context);
-    
+
     /// Handle attribute write access.
     /// Handle attribute write access.
     virtual void OnSetAttribute(const AttributeInfo& attr, const Variant& src);
     virtual void OnSetAttribute(const AttributeInfo& attr, const Variant& src);
     /// Visualize the component as debug geometry.
     /// Visualize the component as debug geometry.
     virtual void DrawDebugGeometry(DebugRenderer* debug, bool depthTest);
     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.
     /// 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);
     void SetBoundingBox(const BoundingBox& box);
     /// Set ambient color
     /// Set ambient color
@@ -71,7 +71,7 @@ public:
     void SetAmbientGradient(bool enable);
     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.
     /// 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);
     void SetZoneTexture(Texture* texture);
-    
+
     /// Return inverse world transform.
     /// Return inverse world transform.
     const Matrix3x4& GetInverseWorldTransform() const;
     const Matrix3x4& GetInverseWorldTransform() const;
     /// Return zone's own ambient color, disregarding gradient mode.
     /// Return zone's own ambient color, disregarding gradient mode.
@@ -100,14 +100,14 @@ public:
     bool GetAmbientGradient() const { return ambientGradient_; }
     bool GetAmbientGradient() const { return ambientGradient_; }
     /// Return zone texture.
     /// Return zone texture.
     Texture* GetZoneTexture() const { return zoneTexture_; }
     Texture* GetZoneTexture() const { return zoneTexture_; }
-    
+
     /// Check whether a point is inside.
     /// Check whether a point is inside.
     bool IsInside(const Vector3& point) const;
     bool IsInside(const Vector3& point) const;
     /// Set zone texture attribute.
     /// Set zone texture attribute.
-    void SetZoneTextureAttr(ResourceRef value);
+    void SetZoneTextureAttr(const ResourceRef& value);
     /// Return zone texture attribute.
     /// Return zone texture attribute.
     ResourceRef GetZoneTextureAttr() const;
     ResourceRef GetZoneTextureAttr() const;
-    
+
 protected:
 protected:
     /// Handle node transform being dirtied.
     /// Handle node transform being dirtied.
     virtual void OnMarkedDirty(Node* node);
     virtual void OnMarkedDirty(Node* node);
@@ -119,7 +119,7 @@ protected:
     void UpdateAmbientGradient();
     void UpdateAmbientGradient();
     /// Clear zone reference from drawables inside the bounding box.
     /// Clear zone reference from drawables inside the bounding box.
     void ClearDrawablesZone();
     void ClearDrawablesZone();
-    
+
     /// Cached inverse world transform matrix.
     /// Cached inverse world transform matrix.
     mutable Matrix3x4 inverseWorld_;
     mutable Matrix3x4 inverseWorld_;
     /// Inverse transform dirty flag.
     /// Inverse transform dirty flag.

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

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

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

@@ -84,9 +84,9 @@ public:
     /// Set script object type.
     /// Set script object type.
     void SetScriptObjectType(const String& scriptObjectType);
     void SetScriptObjectType(const String& scriptObjectType);
     /// Set script file serialization attribute by calling a script function.
     /// 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.
     /// 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.
     /// Script subscribe to an event that can by send by any sender.
     void ScriptSubscribeToEvent(const String& eventName, int functionIndex);
     void ScriptSubscribeToEvent(const String& eventName, int functionIndex);
     /// Script subscribe to an event that can by send by any sender.
     /// Script subscribe to an event that can by send by any sender.
@@ -118,7 +118,7 @@ public:
     WeakPtr<LuaFunction> GetScriptObjectFunction(const String& functionName) const;
     WeakPtr<LuaFunction> GetScriptObjectFunction(const String& functionName) const;
 
 
 	/// Set script file attribute.
 	/// Set script file attribute.
-	void SetScriptFileAttr(ResourceRef value);
+	void SetScriptFileAttr(const ResourceRef& value);
 	/// Return script file attribute.
 	/// Return script file attribute.
 	ResourceRef GetScriptFileAttr() const;
 	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 Update(float timeStep);
     void UpdateCollisions();
     void UpdateCollisions();
     void SetFps(int fps);
     void SetFps(int fps);
-    void SetGravity(Vector3 gravity);
+    void SetGravity(const Vector3& gravity);
     void SetMaxSubSteps(int num);
     void SetMaxSubSteps(int num);
     void SetNumIterations(int num);
     void SetNumIterations(int num);
     void SetInterpolation(bool enable);
     void SetInterpolation(bool enable);

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

@@ -10,19 +10,19 @@ enum CollisionEventMode
 class RigidBody : public Component
 class RigidBody : public Component
 {
 {
     void SetMass(float mass);
     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 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 SetLinearRestThreshold(float threshold);
     void SetLinearDamping(float damping);
     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 SetAngularRestThreshold(float threshold);
     void SetAngularDamping(float factor);
     void SetAngularDamping(float factor);
     void SetFriction(float friction);
     void SetFriction(float friction);
-    void SetAnisotropicFriction(Vector3 friction);
+    void SetAnisotropicFriction(const Vector3& friction);
     void SetRollingFriction(float friction);
     void SetRollingFriction(float friction);
     void SetRestitution(float restitution);
     void SetRestitution(float restitution);
     void SetContactProcessingThreshold(float threshold);
     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 NodeRemoved(Node* node);
     void ComponentAdded(Component* component);
     void ComponentAdded(Component* component);
     void ComponentRemoved(Component* component);
     void ComponentRemoved(Component* component);
-    void SetVarNamesAttr(String value);
+    void SetVarNamesAttr(const String value);
     String GetVarNamesAttr() const;
     String GetVarNamesAttr() const;
     void PrepareNetworkUpdate();
     void PrepareNetworkUpdate();
     void CleanupConnection(Connection* connection);
     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 SetBodyType(BodyType2D bodyType);
     void SetMass(float mass);
     void SetMass(float mass);
     void SetInertia(float inertia);
     void SetInertia(float inertia);
-    void SetMassCenter(Vector2 center);
+    void SetMassCenter(const Vector2& center);
     void SetUseFixtureMass(bool useFixtureMass);
     void SetUseFixtureMass(bool useFixtureMass);
     void SetLinearDamping(float linearDamping);
     void SetLinearDamping(float linearDamping);
     void SetAngularDamping(float angularDamping);
     void SetAngularDamping(float angularDamping);
@@ -21,7 +21,7 @@ class RigidBody2D : Component
     void SetBullet(bool bullet);
     void SetBullet(bool bullet);
     void SetGravityScale(float gravityScale);
     void SetGravityScale(float gravityScale);
     void SetAwake(bool awake);
     void SetAwake(bool awake);
-    void SetLinearVelocity(Vector2 linearVelocity);
+    void SetLinearVelocity(const Vector2& linearVelocity);
     void SetAngularVelocity(float angularVelocity);
     void SetAngularVelocity(float angularVelocity);
     void ApplyForce(const Vector2& force, const Vector2& point,  bool wake);
     void ApplyForce(const Vector2& force, const Vector2& point,  bool wake);
     void ApplyForceToCenter(const Vector2& force, bool wake);
     void ApplyForceToCenter(const Vector2& force, bool wake);

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


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

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

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

@@ -132,7 +132,7 @@ public:
     {
     {
         const Vector<PODVector<CustomGeometryVertex> >& srcVertices = custom->GetVertices();
         const Vector<PODVector<CustomGeometryVertex> >& srcVertices = custom->GetVertices();
         unsigned totalVertexCount = 0;
         unsigned totalVertexCount = 0;
-        
+
         for (unsigned i = 0; i < srcVertices.Size(); ++i)
         for (unsigned i = 0; i < srcVertices.Size(); ++i)
             totalVertexCount += srcVertices[i].Size();
             totalVertexCount += srcVertices[i].Size();
 
 
@@ -143,11 +143,11 @@ public:
             SharedArrayPtr<unsigned char> indexData(new unsigned char[totalVertexCount * sizeof(unsigned)]);
             SharedArrayPtr<unsigned char> indexData(new unsigned char[totalVertexCount * sizeof(unsigned)]);
             dataArrays_.Push(vertexData);
             dataArrays_.Push(vertexData);
             dataArrays_.Push(indexData);
             dataArrays_.Push(indexData);
-            
+
             Vector3* destVertex = reinterpret_cast<Vector3*>(&vertexData[0]);
             Vector3* destVertex = reinterpret_cast<Vector3*>(&vertexData[0]);
             unsigned* destIndex = reinterpret_cast<unsigned*>(&indexData[0]);
             unsigned* destIndex = reinterpret_cast<unsigned*>(&indexData[0]);
             unsigned k = 0;
             unsigned k = 0;
-            
+
             for (unsigned i = 0; i < srcVertices.Size(); ++i)
             for (unsigned i = 0; i < srcVertices.Size(); ++i)
             {
             {
                 for (unsigned j = 0; j < srcVertices[i].Size(); ++j)
                 for (unsigned j = 0; j < srcVertices[i].Size(); ++j)
@@ -156,7 +156,7 @@ public:
                     *destIndex++ = k++;
                     *destIndex++ = k++;
                 }
                 }
             }
             }
-            
+
             btIndexedMesh meshIndex;
             btIndexedMesh meshIndex;
             meshIndex.m_numTriangles = totalVertexCount / 3;
             meshIndex.m_numTriangles = totalVertexCount / 3;
             meshIndex.m_triangleIndexBase = indexData;
             meshIndex.m_triangleIndexBase = indexData;
@@ -169,7 +169,7 @@ public:
             m_indexedMeshes.push_back(meshIndex);
             m_indexedMeshes.push_back(meshIndex);
         }
         }
     }
     }
-    
+
 private:
 private:
     /// Shared vertex/index data used in the collision
     /// Shared vertex/index data used in the collision
     Vector<SharedArrayPtr<unsigned char> > dataArrays_;
     Vector<SharedArrayPtr<unsigned char> > dataArrays_;
@@ -262,7 +262,7 @@ ConvexData::ConvexData(CustomGeometry* custom)
         for (unsigned j = 0; j < srcVertices[i].Size(); ++j)
         for (unsigned j = 0; j < srcVertices[i].Size(); ++j)
             vertices.Push(srcVertices[i][j].position_);
             vertices.Push(srcVertices[i][j].position_);
     }
     }
-    
+
     BuildHull(vertices);
     BuildHull(vertices);
 }
 }
 
 
@@ -388,7 +388,7 @@ void CollisionShape::RegisterObject(Context* context)
     ATTRIBUTE(CollisionShape, VAR_VECTOR3, "Size", size_, Vector3::ONE, 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_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);
     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);
+    MIXED_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_INT, "LOD Level", lodLevel_, 0, AM_DEFAULT);
     ATTRIBUTE(CollisionShape, VAR_FLOAT, "Collision Margin", margin_, DEFAULT_COLLISION_MARGIN, 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);
     ATTRIBUTE(CollisionShape, VAR_INT, "CustomGeometry NodeID", customGeometryID_, 0, AM_DEFAULT | AM_NODEID);
@@ -830,7 +830,7 @@ void CollisionShape::NotifyRigidBody(bool updateMass)
     }
     }
 }
 }
 
 
-void CollisionShape::SetModelAttr(ResourceRef value)
+void CollisionShape::SetModelAttr(const ResourceRef& value)
 {
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     model_ = cache->GetResource<Model>(value.name_);
     model_ = cache->GetResource<Model>(value.name_);

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

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

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

@@ -179,7 +179,7 @@ void PhysicsWorld::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<PhysicsWorld>(SUBSYSTEM_CATEGORY);
     context->RegisterFactory<PhysicsWorld>(SUBSYSTEM_CATEGORY);
 
 
-    ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_VECTOR3, "Gravity", GetGravity, SetGravity, Vector3, DEFAULT_GRAVITY, AM_DEFAULT);
+    MIXED_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, "Physics FPS", fps_, DEFAULT_FPS, AM_DEFAULT);
     ATTRIBUTE(PhysicsWorld, VAR_INT, "Max Substeps", maxSubSteps_, 0, 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);
     ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_INT, "Solver Iterations", GetNumIterations, SetNumIterations, int, 10, AM_DEFAULT);
@@ -226,7 +226,7 @@ void PhysicsWorld::drawContactPoint(const btVector3& pointOnB, const btVector3&
 }
 }
 
 
 void PhysicsWorld::draw3dText(const btVector3& location, const char* textString)
 void PhysicsWorld::draw3dText(const btVector3& location, const char* textString)
-{ 
+{
 }
 }
 
 
 void PhysicsWorld::Update(float timeStep)
 void PhysicsWorld::Update(float timeStep)
@@ -242,7 +242,7 @@ void PhysicsWorld::Update(float timeStep)
     }
     }
     else if (maxSubSteps_ > 0)
     else if (maxSubSteps_ > 0)
         maxSubSteps = Min(maxSubSteps, maxSubSteps_);
         maxSubSteps = Min(maxSubSteps, maxSubSteps_);
-    
+
     delayedWorldTransforms_.Clear();
     delayedWorldTransforms_.Clear();
 
 
     if (interpolation_)
     if (interpolation_)
@@ -284,14 +284,14 @@ void PhysicsWorld::UpdateCollisions()
 void PhysicsWorld::SetFps(int fps)
 void PhysicsWorld::SetFps(int fps)
 {
 {
     fps_ = Clamp(fps, 1, 1000);
     fps_ = Clamp(fps, 1, 1000);
-    
+
     MarkNetworkUpdate();
     MarkNetworkUpdate();
 }
 }
 
 
-void PhysicsWorld::SetGravity(Vector3 gravity)
+void PhysicsWorld::SetGravity(const Vector3& gravity)
 {
 {
     world_->setGravity(ToBtVector3(gravity));
     world_->setGravity(ToBtVector3(gravity));
-    
+
     MarkNetworkUpdate();
     MarkNetworkUpdate();
 }
 }
 
 
@@ -305,7 +305,7 @@ void PhysicsWorld::SetNumIterations(int num)
 {
 {
     num = Clamp(num, 1, MAX_SOLVER_ITERATIONS);
     num = Clamp(num, 1, MAX_SOLVER_ITERATIONS);
     world_->getSolverInfo().m_numIterations = num;
     world_->getSolverInfo().m_numIterations = num;
-    
+
     MarkNetworkUpdate();
     MarkNetworkUpdate();
 }
 }
 
 
@@ -317,21 +317,21 @@ void PhysicsWorld::SetInterpolation(bool enable)
 void PhysicsWorld::SetInternalEdge(bool enable)
 void PhysicsWorld::SetInternalEdge(bool enable)
 {
 {
     internalEdge_ = enable;
     internalEdge_ = enable;
-    
+
     MarkNetworkUpdate();
     MarkNetworkUpdate();
 }
 }
 
 
 void PhysicsWorld::SetSplitImpulse(bool enable)
 void PhysicsWorld::SetSplitImpulse(bool enable)
 {
 {
     world_->getSolverInfo().m_splitImpulse = enable;
     world_->getSolverInfo().m_splitImpulse = enable;
-    
+
     MarkNetworkUpdate();
     MarkNetworkUpdate();
 }
 }
 
 
 void PhysicsWorld::SetMaxNetworkAngularVelocity(float velocity)
 void PhysicsWorld::SetMaxNetworkAngularVelocity(float velocity)
 {
 {
     maxNetworkAngularVelocity_ = Clamp(velocity, 1.0f, 32767.0f);
     maxNetworkAngularVelocity_ = Clamp(velocity, 1.0f, 32767.0f);
-    
+
     MarkNetworkUpdate();
     MarkNetworkUpdate();
 }
 }
 
 
@@ -427,7 +427,7 @@ void PhysicsWorld::ConvexCast(PhysicsRaycastResult& result, CollisionShape* shap
         result.distance_ = M_INFINITY;
         result.distance_ = M_INFINITY;
         return;
         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
     // 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>();
     RigidBody* bodyComp = shape->GetComponent<RigidBody>();
     btRigidBody* body = bodyComp ? bodyComp->GetBody() : (btRigidBody*)0;
     btRigidBody* body = bodyComp ? bodyComp->GetBody() : (btRigidBody*)0;
@@ -457,7 +457,7 @@ void PhysicsWorld::ConvexCast(PhysicsRaycastResult& result, btCollisionShape* sh
         result.distance_ = M_INFINITY;
         result.distance_ = M_INFINITY;
         return;
         return;
     }
     }
-    
+
     if (!shape->isConvex())
     if (!shape->isConvex())
     {
     {
         LOGERROR("Can not use non-convex collision shape for convex cast");
         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;
         result.distance_ = M_INFINITY;
         return;
         return;
     }
     }
-    
+
     PROFILE(PhysicsConvexCast);
     PROFILE(PhysicsConvexCast);
 
 
     btCollisionWorld::ClosestConvexResultCallback convexCallback(ToBtVector3(startPos), ToBtVector3(endPos));
     btCollisionWorld::ClosestConvexResultCallback convexCallback(ToBtVector3(startPos), ToBtVector3(endPos));
@@ -715,7 +715,7 @@ void PhysicsWorld::SendCollisionEvents()
     currentCollisions_.Clear();
     currentCollisions_.Clear();
     physicsCollisionData_.Clear();
     physicsCollisionData_.Clear();
     nodeCollisionData_.Clear();
     nodeCollisionData_.Clear();
-    
+
     int numManifolds = collisionDispatcher_->getNumManifolds();
     int numManifolds = collisionDispatcher_->getNumManifolds();
 
 
     if (numManifolds)
     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.
     /// 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_; }
     bool operator != (const PhysicsRaycastResult& rhs) const { return position_ != rhs.position_ || normal_ != rhs.normal_ || distance_ != rhs.distance_ || body_ != rhs.body_; }
-    
+
     /// Hit worldspace position.
     /// Hit worldspace position.
     Vector3 position_;
     Vector3 position_;
     /// Hit worldspace normal.
     /// Hit worldspace normal.
@@ -133,7 +133,7 @@ public:
     /// Set simulation substeps per second.
     /// Set simulation substeps per second.
     void SetFps(int fps);
     void SetFps(int fps);
     /// Set gravity.
     /// 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.
     /// 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);
     void SetMaxSubSteps(int num);
     /// Set number of constraint solver iterations.
     /// Set number of constraint solver iterations.
@@ -164,7 +164,7 @@ public:
     void GetRigidBodies(PODVector<RigidBody*>& result, const BoundingBox& box, unsigned collisionMask = M_MAX_UNSIGNED);
     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.
     /// 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);
     void GetRigidBodies(PODVector<RigidBody*>& result, const RigidBody* body);
-    
+
     /// Return gravity.
     /// Return gravity.
     Vector3 GetGravity() const;
     Vector3 GetGravity() const;
     /// Return maximum number of physics substeps per frame.
     /// Return maximum number of physics substeps per frame.

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

@@ -103,17 +103,17 @@ void RigidBody::RegisterObject(Context* context)
     context->RegisterFactory<RigidBody>(PHYSICS_CATEGORY);
     context->RegisterFactory<RigidBody>(PHYSICS_CATEGORY);
 
 
     ACCESSOR_ATTRIBUTE(RigidBody, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
     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);
+    MIXED_ACCESSOR_ATTRIBUTE(RigidBody, VAR_QUATERNION, "Physics Rotation", GetRotation, SetRotation, Quaternion, Quaternion::IDENTITY, AM_FILE | AM_NOEDIT);
+    MIXED_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);
     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_FLOAT, "Friction", GetFriction, SetFriction, float, DEFAULT_FRICTION, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(RigidBody, VAR_VECTOR3, "Anisotropic Friction", GetAnisotropicFriction, SetAnisotropicFriction, Vector3, Vector3::ONE, AM_DEFAULT);
+    MIXED_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, "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_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);
+    MIXED_ACCESSOR_ATTRIBUTE(RigidBody, VAR_VECTOR3, "Linear Velocity", GetLinearVelocity, SetLinearVelocity, Vector3, Vector3::ZERO, AM_DEFAULT | AM_LATESTDATA);
+    MIXED_ACCESSOR_ATTRIBUTE(RigidBody, VAR_VECTOR3, "Angular Velocity", GetAngularVelocity, SetAngularVelocity, Vector3, Vector3::ZERO, AM_FILE);
+    MIXED_ACCESSOR_ATTRIBUTE(RigidBody, VAR_VECTOR3, "Linear Factor", GetLinearFactor, SetLinearFactor, Vector3, Vector3::ONE, AM_DEFAULT);
+    MIXED_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, "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, "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, "Linear Rest Threshold", GetLinearRestThreshold, SetLinearRestThreshold, float, 0.8f, AM_DEFAULT);
@@ -228,7 +228,7 @@ void RigidBody::SetMass(float mass)
     }
     }
 }
 }
 
 
-void RigidBody::SetPosition(Vector3 position)
+void RigidBody::SetPosition(const Vector3& position)
 {
 {
     if (body_)
     if (body_)
     {
     {
@@ -245,7 +245,7 @@ void RigidBody::SetPosition(Vector3 position)
     }
     }
 }
 }
 
 
-void RigidBody::SetRotation(Quaternion rotation)
+void RigidBody::SetRotation(const Quaternion& rotation)
 {
 {
     if (body_)
     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_)
     if (body_)
     {
     {
@@ -297,7 +297,7 @@ void RigidBody::SetLinearVelocity(Vector3 velocity)
     }
     }
 }
 }
 
 
-void RigidBody::SetLinearFactor(Vector3 factor)
+void RigidBody::SetLinearFactor(const Vector3& factor)
 {
 {
     if (body_)
     if (body_)
     {
     {
@@ -324,7 +324,7 @@ void RigidBody::SetLinearDamping(float damping)
     }
     }
 }
 }
 
 
-void RigidBody::SetAngularVelocity(Vector3 velocity)
+void RigidBody::SetAngularVelocity(const Vector3& velocity)
 {
 {
     if (body_)
     if (body_)
     {
     {
@@ -335,7 +335,7 @@ void RigidBody::SetAngularVelocity(Vector3 velocity)
     }
     }
 }
 }
 
 
-void RigidBody::SetAngularFactor(Vector3 factor)
+void RigidBody::SetAngularFactor(const Vector3& factor)
 {
 {
     if (body_)
     if (body_)
     {
     {
@@ -371,7 +371,7 @@ void RigidBody::SetFriction(float friction)
     }
     }
 }
 }
 
 
-void RigidBody::SetAnisotropicFriction(Vector3 friction)
+void RigidBody::SetAnisotropicFriction(const Vector3& friction)
 {
 {
     if (body_)
     if (body_)
     {
     {
@@ -705,7 +705,7 @@ void RigidBody::ApplyWorldTransform(const Vector3& newWorldPosition, const Quate
     // where node is already null
     // where node is already null
     if (!node_ || !physicsWorld_)
     if (!node_ || !physicsWorld_)
         return;
         return;
-    
+
     physicsWorld_->SetApplyingTransforms(true);
     physicsWorld_->SetApplyingTransforms(true);
 
 
     // Apply transform to the SmoothedTransform component instead of node transform if available
     // 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
 class URHO3D_API RigidBody : public Component, public btMotionState
 {
 {
     OBJECT(RigidBody);
     OBJECT(RigidBody);
-    
+
 public:
 public:
     /// Construct.
     /// Construct.
     RigidBody(Context* context);
     RigidBody(Context* context);
@@ -58,7 +58,7 @@ public:
     virtual ~RigidBody();
     virtual ~RigidBody();
     /// Register object factory.
     /// Register object factory.
     static void RegisterObject(Context* context);
     static void RegisterObject(Context* context);
-    
+
     /// Handle attribute write access.
     /// Handle attribute write access.
     virtual void OnSetAttribute(const AttributeInfo& attr, const Variant& src);
     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.
     /// 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);
     virtual void setWorldTransform(const btTransform &worldTrans);
     /// Visualize the component as debug geometry.
     /// Visualize the component as debug geometry.
     virtual void DrawDebugGeometry(DebugRenderer* debug, bool depthTest);
     virtual void DrawDebugGeometry(DebugRenderer* debug, bool depthTest);
-    
+
     /// Set mass. Zero mass makes the body static.
     /// Set mass. Zero mass makes the body static.
     void SetMass(float mass);
     void SetMass(float mass);
     /// Set rigid body position in world space.
     /// Set rigid body position in world space.
-    void SetPosition(Vector3 position);
+    void SetPosition(const Vector3& position);
     /// Set rigid body rotation in world space.
     /// 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.
     /// Set rigid body position and rotation in world space as an atomic operation.
     void SetTransform(const Vector3& position, const Quaternion& rotation);
     void SetTransform(const Vector3& position, const Quaternion& rotation);
     /// Set linear velocity.
     /// 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).
     /// 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.
     /// Set linear velocity deactivation threshold.
     void SetLinearRestThreshold(float threshold);
     void SetLinearRestThreshold(float threshold);
     /// Set linear velocity damping factor.
     /// Set linear velocity damping factor.
     void SetLinearDamping(float damping);
     void SetLinearDamping(float damping);
     /// Set angular velocity.
     /// 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).
     /// 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.
     /// Set angular velocity deactivation threshold.
     void SetAngularRestThreshold(float threshold);
     void SetAngularRestThreshold(float threshold);
     /// Set angular velocity damping factor.
     /// Set angular velocity damping factor.
@@ -99,7 +99,7 @@ public:
     /// Set friction coefficient.
     /// Set friction coefficient.
     void SetFriction(float friction);
     void SetFriction(float friction);
     /// Set anisotropic friction.
     /// Set anisotropic friction.
-    void SetAnisotropicFriction(Vector3 friction);
+    void SetAnisotropicFriction(const Vector3& friction);
     /// Set rolling friction coefficient.
     /// Set rolling friction coefficient.
     void SetRollingFriction(float friction);
     void SetRollingFriction(float friction);
     /// Set restitution coefficient.
     /// Set restitution coefficient.
@@ -148,7 +148,7 @@ public:
     void DisableMassUpdate();
     void DisableMassUpdate();
     /// Re-enable mass update and recalculate the mass/inertia by calling UpdateMass(). Call when collision shape changes are finished.
     /// Re-enable mass update and recalculate the mass/inertia by calling UpdateMass(). Call when collision shape changes are finished.
     void EnableMassUpdate();
     void EnableMassUpdate();
-    
+
     /// Return physics world.
     /// Return physics world.
     PhysicsWorld* GetPhysicsWorld() const { return physicsWorld_; }
     PhysicsWorld* GetPhysicsWorld() const { return physicsWorld_; }
     /// Return Bullet rigid body.
     /// Return Bullet rigid body.
@@ -213,7 +213,7 @@ public:
     CollisionEventMode GetCollisionEventMode() const { return collisionEventMode_; }
     CollisionEventMode GetCollisionEventMode() const { return collisionEventMode_; }
     /// Return colliding rigid bodies from the last simulation step.
     /// Return colliding rigid bodies from the last simulation step.
     void GetCollidingBodies(PODVector<RigidBody*>& result) const;
     void GetCollidingBodies(PODVector<RigidBody*>& result) const;
-    
+
     /// Apply new world transform after a simulation step. Called internally.
     /// Apply new world transform after a simulation step. Called internally.
     void ApplyWorldTransform(const Vector3& newWorldPosition, const Quaternion& newWorldRotation);
     void ApplyWorldTransform(const Vector3& newWorldPosition, const Quaternion& newWorldRotation);
     /// Update mass and inertia to the Bullet rigid body.
     /// Update mass and inertia to the Bullet rigid body.
@@ -230,13 +230,13 @@ public:
     void RemoveConstraint(Constraint* constraint);
     void RemoveConstraint(Constraint* constraint);
     /// Remove the rigid body.
     /// Remove the rigid body.
     void ReleaseBody();
     void ReleaseBody();
-    
+
 protected:
 protected:
     /// Handle node being assigned.
     /// Handle node being assigned.
     virtual void OnNodeSet(Node* node);
     virtual void OnNodeSet(Node* node);
     /// Handle node transform being dirtied.
     /// Handle node transform being dirtied.
     virtual void OnMarkedDirty(Node* node);
     virtual void OnMarkedDirty(Node* node);
-    
+
 private:
 private:
     /// Create the rigid body, or re-add to the physics world with changed flags. Calls UpdateMass().
     /// Create the rigid body, or re-add to the physics world with changed flags. Calls UpdateMass().
     void AddBodyToWorld();
     void AddBodyToWorld();
@@ -246,7 +246,7 @@ private:
     void HandleTargetPosition(StringHash eventType, VariantMap& eventData);
     void HandleTargetPosition(StringHash eventType, VariantMap& eventData);
     /// Handle SmoothedTransform target rotation update.
     /// Handle SmoothedTransform target rotation update.
     void HandleTargetRotation(StringHash eventType, VariantMap& eventData);
     void HandleTargetRotation(StringHash eventType, VariantMap& eventData);
-    
+
     /// Bullet rigid body.
     /// Bullet rigid body.
     btRigidBody* body_;
     btRigidBody* body_;
     /// Bullet compound collision shape.
     /// Bullet compound collision shape.

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

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

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

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

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

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

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

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

+ 39 - 0
Source/Engine/Scene/Serializable.h

@@ -203,6 +203,44 @@ public:
     SetFunctionPtr setFunction_;
     SetFunctionPtr setFunction_;
 };
 };
 
 
+/// Template implementation of the attribute accessor invoke helper class using const references for setter only.
+template <class T, class U> class MixedAttributeAccessorImpl : public AttributeAccessor
+{
+public:
+    typedef U (T::*GetFunctionPtr)() const;
+    typedef void (T::*SetFunctionPtr)(const U&);
+
+    /// Construct with function pointers.
+    MixedAttributeAccessorImpl(GetFunctionPtr getFunction, SetFunctionPtr setFunction) :
+        getFunction_(getFunction),
+        setFunction_(setFunction)
+    {
+        assert(getFunction_);
+        assert(setFunction_);
+    }
+
+    /// Invoke getter function.
+    virtual void Get(const Serializable* ptr, Variant& dest) const
+    {
+        assert(ptr);
+        const T* classPtr = static_cast<const T*>(ptr);
+        dest = (classPtr->*getFunction_)();
+    }
+
+    /// Invoke setter function.
+    virtual void Set(Serializable* ptr, const Variant& value)
+    {
+        assert(ptr);
+        T* classPtr = static_cast<T*>(ptr);
+        (classPtr->*setFunction_)(value.Get<U>());
+    }
+
+    /// Class-specific pointer to getter function.
+    GetFunctionPtr getFunction_;
+    /// Class-specific pointer to setter function.
+    SetFunctionPtr setFunction_;
+};
+
 #define COPY_BASE_ATTRIBUTES(className, sourceClassName) context->CopyBaseAttributes<sourceClassName, className>()
 #define COPY_BASE_ATTRIBUTES(className, sourceClassName) context->CopyBaseAttributes<sourceClassName, className>()
 #define REMOVE_ATTRIBUTE(className, name) context->RemoveAttribute<className>(name)
 #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 ATTRIBUTE(className, type, name, variable, defaultValue, mode) context->RegisterAttribute<className>(Urho3D::AttributeInfo(type, name, offsetof(className, variable), defaultValue, mode))
@@ -210,6 +248,7 @@ public:
 #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 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 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 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 MIXED_ACCESSOR_ATTRIBUTE(className, type, name, getFunction, setFunction, typeName, defaultValue, mode) context->RegisterAttribute<className>(Urho3D::AttributeInfo(type, name, new Urho3D::MixedAttributeAccessorImpl<className, typeName>(&className::getFunction, &className::setFunction), defaultValue, mode))
 #define UPDATE_ATTRIBUTE_DEFAULT_VALUE(className, name, defaultValue) context->UpdateAttributeDefaultValue<className>(name, defaultValue)
 #define UPDATE_ATTRIBUTE_DEFAULT_VALUE(className, name, defaultValue) context->UpdateAttributeDefaultValue<className>(name, defaultValue)
 
 
 }
 }

+ 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_TRIANGLEMESH", SHAPE_TRIANGLEMESH);
     engine->RegisterEnumValue("ShapeType", "SHAPE_CONVEXHULL", SHAPE_CONVEXHULL);
     engine->RegisterEnumValue("ShapeType", "SHAPE_CONVEXHULL", SHAPE_CONVEXHULL);
     engine->RegisterEnumValue("ShapeType", "SHAPE_TERRAIN", SHAPE_TERRAIN);
     engine->RegisterEnumValue("ShapeType", "SHAPE_TERRAIN", SHAPE_TERRAIN);
-    
+
     RegisterComponent<CollisionShape>(engine, "CollisionShape");
     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 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);
     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_NEVER", COLLISION_NEVER);
     engine->RegisterEnumValue("CollisionEventMode", "COLLISION_ACTIVE", COLLISION_ACTIVE);
     engine->RegisterEnumValue("CollisionEventMode", "COLLISION_ACTIVE", COLLISION_ACTIVE);
     engine->RegisterEnumValue("CollisionEventMode", "COLLISION_ALWAYS", COLLISION_ALWAYS);
     engine->RegisterEnumValue("CollisionEventMode", "COLLISION_ALWAYS", COLLISION_ALWAYS);
-    
+
     RegisterComponent<RigidBody>(engine, "RigidBody");
     RegisterComponent<RigidBody>(engine, "RigidBody");
     engine->RegisterObjectMethod("RigidBody", "void SetTransform(const Vector3&in, const Quaternion&in)", asMETHOD(RigidBody, SetTransform), asCALL_THISCALL);
     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);
     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", "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", "void set_mass(float)", asMETHOD(RigidBody, SetMass), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "float get_mass() const", asMETHOD(RigidBody, GetMass), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "float get_mass() const", asMETHOD(RigidBody, GetMass), asCALL_THISCALL);
-    engine->RegisterObjectMethod("RigidBody", "void set_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", "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", "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", "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", "Vector3 get_linearFactor() const", asMETHOD(RigidBody, GetLinearFactor), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "void set_linearRestThreshold(float)", asMETHOD(RigidBody, SetLinearRestThreshold), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "void set_linearRestThreshold(float)", asMETHOD(RigidBody, SetLinearRestThreshold), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "float get_linearRestThreshold() const", asMETHOD(RigidBody, GetLinearRestThreshold), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "float get_linearRestThreshold() const", asMETHOD(RigidBody, GetLinearRestThreshold), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "void set_linearDamping(float)", asMETHOD(RigidBody, SetLinearDamping), 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", "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", "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", "Vector3 get_angularFactor() const", asMETHOD(RigidBody, GetAngularFactor), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "void set_angularRestThreshold(float)", asMETHOD(RigidBody, SetAngularRestThreshold), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "void set_angularRestThreshold(float)", asMETHOD(RigidBody, SetAngularRestThreshold), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "float get_angularRestThreshold() const", asMETHOD(RigidBody, GetAngularRestThreshold), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "float get_angularRestThreshold() const", asMETHOD(RigidBody, GetAngularRestThreshold), asCALL_THISCALL);
@@ -157,7 +157,7 @@ static void RegisterRigidBody(asIScriptEngine* engine)
     engine->RegisterObjectMethod("RigidBody", "float get_angularDamping() const", asMETHOD(RigidBody, GetAngularDamping), asCALL_THISCALL);
     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", "void set_friction(float)", asMETHOD(RigidBody, SetFriction), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "float get_friction() const", asMETHOD(RigidBody, GetFriction), 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", "Vector3 get_anisotropicFriction() const", asMETHOD(RigidBody, GetAnisotropicFriction), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody", "void set_rollingFriction(float)", asMETHOD(RigidBody, SetRollingFriction), 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);
     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_HINGE", CONSTRAINT_HINGE);
     engine->RegisterEnumValue("ConstraintType", "CONSTRAINT_SLIDER", CONSTRAINT_SLIDER);
     engine->RegisterEnumValue("ConstraintType", "CONSTRAINT_SLIDER", CONSTRAINT_SLIDER);
     engine->RegisterEnumValue("ConstraintType", "CONSTRAINT_CONETWIST", CONSTRAINT_CONETWIST);
     engine->RegisterEnumValue("ConstraintType", "CONSTRAINT_CONETWIST", CONSTRAINT_CONETWIST);
-    
+
     RegisterComponent<Constraint>(engine, "Constraint");
     RegisterComponent<Constraint>(engine, "Constraint");
     engine->RegisterObjectMethod("Constraint", "void set_constraintType(ConstraintType)", asMETHOD(Constraint, SetConstraintType), asCALL_THISCALL);
     engine->RegisterObjectMethod("Constraint", "void set_constraintType(ConstraintType)", asMETHOD(Constraint, SetConstraintType), asCALL_THISCALL);
     engine->RegisterObjectMethod("Constraint", "ConstraintType get_constraintType() const", asMETHOD(Constraint, GetConstraintType), 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", "Vector3 normal", offsetof(PhysicsRaycastResult, normal_));
     engine->RegisterObjectProperty("PhysicsRaycastResult", "float distance", offsetof(PhysicsRaycastResult, distance_));
     engine->RegisterObjectProperty("PhysicsRaycastResult", "float distance", offsetof(PhysicsRaycastResult, distance_));
     engine->RegisterObjectMethod("PhysicsRaycastResult", "RigidBody@+ get_body() const", asFUNCTION(PhysicsRaycastResultGetRigidBody), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("PhysicsRaycastResult", "RigidBody@+ get_body() const", asFUNCTION(PhysicsRaycastResultGetRigidBody), asCALL_CDECL_OBJLAST);
-    
+
     RegisterComponent<PhysicsWorld>(engine, "PhysicsWorld");
     RegisterComponent<PhysicsWorld>(engine, "PhysicsWorld");
     engine->RegisterObjectMethod("PhysicsWorld", "void Update(float)", asMETHOD(PhysicsWorld, Update), asCALL_THISCALL);
     engine->RegisterObjectMethod("PhysicsWorld", "void Update(float)", asMETHOD(PhysicsWorld, Update), asCALL_THISCALL);
     engine->RegisterObjectMethod("PhysicsWorld", "void UpdateCollisions()", asMETHOD(PhysicsWorld, UpdateCollisions), 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", "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 DrawDebugGeometry(bool)", asMETHODPR(PhysicsWorld, DrawDebugGeometry, (bool), void), asCALL_THISCALL);
     engine->RegisterObjectMethod("PhysicsWorld", "void RemoveCachedGeometry(Model@+)", asMETHOD(PhysicsWorld, RemoveCachedGeometry), 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", "Vector3 get_gravity() const", asMETHOD(PhysicsWorld, GetGravity), asCALL_THISCALL);
     engine->RegisterObjectMethod("PhysicsWorld", "void set_maxSubSteps(int)", asMETHOD(PhysicsWorld, SetMaxSubSteps), 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);
     engine->RegisterObjectMethod("PhysicsWorld", "int get_maxSubSteps() const", asMETHOD(PhysicsWorld, GetMaxSubSteps), asCALL_THISCALL);

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

@@ -81,11 +81,11 @@ void ScriptInstance::RegisterObject(Context* context)
     context->RegisterFactory<ScriptInstance>(LOGIC_CATEGORY);
     context->RegisterFactory<ScriptInstance>(LOGIC_CATEGORY);
 
 
     ACCESSOR_ATTRIBUTE(ScriptInstance, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
     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);
+    MIXED_ACCESSOR_ATTRIBUTE(ScriptInstance, VAR_BUFFER, "Delayed Method Calls", GetDelayedCallsAttr, SetDelayedCallsAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_FILE | AM_NOEDIT);
+    MIXED_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);
     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);
+    MIXED_ACCESSOR_ATTRIBUTE(ScriptInstance, VAR_BUFFER, "Script Data", GetScriptDataAttr, SetScriptDataAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_FILE | AM_NOEDIT);
+    MIXED_ACCESSOR_ATTRIBUTE(ScriptInstance, VAR_BUFFER, "Script Network Data", GetScriptNetworkDataAttr, SetScriptNetworkDataAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_NET | AM_NOEDIT);
 }
 }
 
 
 void ScriptInstance::OnSetAttribute(const AttributeInfo& attr, const Variant& src)
 void ScriptInstance::OnSetAttribute(const AttributeInfo& attr, const Variant& src)
@@ -353,13 +353,13 @@ void ScriptInstance::RemoveEventHandlersExcept(const PODVector<StringHash>& exce
     UnsubscribeFromAllEventsExcept(exceptions, true);
     UnsubscribeFromAllEventsExcept(exceptions, true);
 }
 }
 
 
-void ScriptInstance::SetScriptFileAttr(ResourceRef value)
+void ScriptInstance::SetScriptFileAttr(const ResourceRef& value)
 {
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SetScriptFile(cache->GetResource<ScriptFile>(value.name_));
     SetScriptFile(cache->GetResource<ScriptFile>(value.name_));
 }
 }
 
 
-void ScriptInstance::SetDelayedCallsAttr(PODVector<unsigned char> value)
+void ScriptInstance::SetDelayedCallsAttr(const PODVector<unsigned char>& value)
 {
 {
     MemoryBuffer buf(value);
     MemoryBuffer buf(value);
     delayedCalls_.Resize(buf.ReadVLE());
     delayedCalls_.Resize(buf.ReadVLE());
@@ -376,7 +376,7 @@ void ScriptInstance::SetDelayedCallsAttr(PODVector<unsigned char> value)
         UpdateEventSubscription();
         UpdateEventSubscription();
 }
 }
 
 
-void ScriptInstance::SetScriptDataAttr(PODVector<unsigned char> data)
+void ScriptInstance::SetScriptDataAttr(const PODVector<unsigned char>& data)
 {
 {
     if (scriptObject_ && methods_[METHOD_LOAD])
     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])
     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
 class URHO3D_API ScriptInstance : public Component, public ScriptEventListener
 {
 {
     OBJECT(ScriptInstance);
     OBJECT(ScriptInstance);
-    
+
 public:
 public:
     /// Construct.
     /// Construct.
     ScriptInstance(Context* context);
     ScriptInstance(Context* context);
@@ -65,7 +65,7 @@ public:
     virtual ~ScriptInstance();
     virtual ~ScriptInstance();
     /// Register object factory.
     /// Register object factory.
     static void RegisterObject(Context* context);
     static void RegisterObject(Context* context);
-    
+
     /// Handle attribute write access.
     /// Handle attribute write access.
     virtual void OnSetAttribute(const AttributeInfo& attr, const Variant& src);
     virtual void OnSetAttribute(const AttributeInfo& attr, const Variant& src);
     /// Handle attribute read access.
     /// Handle attribute read access.
@@ -106,24 +106,24 @@ public:
     void DelayedExecute(float delay, bool repeat, const String& declaration, const VariantVector& parameters = Variant::emptyVariantVector);
     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.
     /// Clear pending delay-executed method calls. If empty declaration given, clears all.
     void ClearDelayedExecute(const String& declaration = String::EMPTY);
     void ClearDelayedExecute(const String& declaration = String::EMPTY);
-    
+
     /// Return script file.
     /// Return script file.
     ScriptFile* GetScriptFile() const { return scriptFile_; }
     ScriptFile* GetScriptFile() const { return scriptFile_; }
     /// Return script object.
     /// Return script object.
     asIScriptObject* GetScriptObject() const { return scriptObject_; }
     asIScriptObject* GetScriptObject() const { return scriptObject_; }
     /// Return class name.
     /// Return class name.
     const String& GetClassName() const { return className_; }
     const String& GetClassName() const { return className_; }
-    
+
     /// Set script file attribute.
     /// Set script file attribute.
-    void SetScriptFileAttr(ResourceRef value);
+    void SetScriptFileAttr(const ResourceRef& value);
     /// Set delayed method calls attribute.
     /// Set delayed method calls attribute.
-    void SetDelayedCallsAttr(PODVector<unsigned char> value);
+    void SetDelayedCallsAttr(const PODVector<unsigned char>& value);
     /// Set fixed update time accumulator attribute.
     /// Set fixed update time accumulator attribute.
     void SetFixedUpdateAccAttr(float value);
     void SetFixedUpdateAccAttr(float value);
     /// Set script file serialization attribute by calling a script function.
     /// 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.
     /// 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.
     /// Return script file attribute.
     ResourceRef GetScriptFileAttr() const;
     ResourceRef GetScriptFileAttr() const;
     /// Return delayed method calls attribute.
     /// Return delayed method calls attribute.
@@ -134,11 +134,11 @@ public:
     PODVector<unsigned char> GetScriptDataAttr() const;
     PODVector<unsigned char> GetScriptDataAttr() const;
     /// Get script network serialization attribute by calling a script function.
     /// Get script network serialization attribute by calling a script function.
     PODVector<unsigned char> GetScriptNetworkDataAttr() const;
     PODVector<unsigned char> GetScriptNetworkDataAttr() const;
-    
+
 protected:
 protected:
     /// Handle node transform being dirtied.
     /// Handle node transform being dirtied.
     virtual void OnMarkedDirty(Node* node);
     virtual void OnMarkedDirty(Node* node);
-    
+
 private:
 private:
     /// (Re)create the script object and check for supported methods if successfully created.
     /// (Re)create the script object and check for supported methods if successfully created.
     void CreateObject();
     void CreateObject();
@@ -170,7 +170,7 @@ private:
     void HandleScriptFileReload(StringHash eventType, VariantMap& eventData);
     void HandleScriptFileReload(StringHash eventType, VariantMap& eventData);
     /// Handle script file reload finished.
     /// Handle script file reload finished.
     void HandleScriptFileReloadFinished(StringHash eventType, VariantMap& eventData);
     void HandleScriptFileReloadFinished(StringHash eventType, VariantMap& eventData);
-    
+
     /// Script subsystem.
     /// Script subsystem.
     SharedPtr<Script> script_;
     SharedPtr<Script> script_;
     /// Script file.
     /// 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", "uint get_numObjects() const", asMETHOD(TileMapLayer2D, GetNumObjects), asCALL_THISCALL);
     engine->RegisterObjectMethod("TileMapLayer2D", "TileMapObject2D@ GetObject(uint) const", asMETHOD(TileMapLayer2D, GetObject), 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);
     engine->RegisterObjectMethod("TileMapLayer2D", "Node@ GetObjectNode(uint) const", asMETHOD(TileMapLayer2D, GetObjectNode), asCALL_THISCALL);
-    
+
     // For image layer only
     // For image layer only
     engine->RegisterObjectMethod("TileMapLayer2D", "Node@ get_imageNode() const", asMETHOD(TileMapLayer2D, GetImageNode), asCALL_THISCALL);
     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", "float get_mass() const", asMETHOD(RigidBody2D, GetMass), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody2D", "void set_inertia(float)", asMETHOD(RigidBody2D, SetInertia), 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", "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", "Vector2 get_massCenter() const", asMETHOD(RigidBody2D, GetMassCenter), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody2D", "void set_useFixtureMass(bool)", asMETHOD(RigidBody2D, SetUseFixtureMass), 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);
     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", "float get_gravityScale() const", asMETHOD(RigidBody2D, GetGravityScale), asCALL_THISCALL);
     engine->RegisterObjectMethod("RigidBody2D", "void set_awake(bool)", asMETHOD(RigidBody2D, SetAwake), 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", "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", "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 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);
     engine->RegisterObjectMethod("RigidBody2D", "void ApplyForceToCenter(const Vector2&in, bool)", asMETHOD(RigidBody2D, ApplyForceToCenter), asCALL_THISCALL);

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

@@ -59,7 +59,7 @@ void BorderImage::RegisterObject(Context* context)
     context->RegisterFactory<BorderImage>(UI_CATEGORY);
     context->RegisterFactory<BorderImage>(UI_CATEGORY);
 
 
     COPY_BASE_ATTRIBUTES(BorderImage, UIElement);
     COPY_BASE_ATTRIBUTES(BorderImage, UIElement);
-    ACCESSOR_ATTRIBUTE(BorderImage, VAR_RESOURCEREF, "Texture", GetTextureAttr, SetTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_FILE);
+    MIXED_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, "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, "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_INTRECT, "Image Border", GetImageBorder, SetImageBorder, IntRect, IntRect::ZERO, AM_FILE);
@@ -198,7 +198,7 @@ void BorderImage::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vert
     hovering_ = false;
     hovering_ = false;
 }
 }
 
 
-void BorderImage::SetTextureAttr(ResourceRef value)
+void BorderImage::SetTextureAttr(const ResourceRef& value)
 {
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SetTexture(cache->GetResource<Texture2D>(value.name_));
     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
 class URHO3D_API BorderImage : public UIElement
 {
 {
     OBJECT(BorderImage);
     OBJECT(BorderImage);
-    
+
 public:
 public:
     /// Construct.
     /// Construct.
     BorderImage(Context* context);
     BorderImage(Context* context);
@@ -43,10 +43,10 @@ public:
     virtual ~BorderImage();
     virtual ~BorderImage();
     /// Register object factory.
     /// Register object factory.
     static void RegisterObject(Context* context);
     static void RegisterObject(Context* context);
-    
+
     /// Return UI rendering batches.
     /// Return UI rendering batches.
     virtual void GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor);
     virtual void GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor);
-    
+
     /// Set texture.
     /// Set texture.
     void SetTexture(Texture* texture);
     void SetTexture(Texture* texture);
     /// Set part of texture to use as the image.
     /// Set part of texture to use as the image.
@@ -65,7 +65,7 @@ public:
     void SetBlendMode(BlendMode mode);
     void SetBlendMode(BlendMode mode);
     /// Set tiled mode.
     /// Set tiled mode.
     void SetTiled(bool enable);
     void SetTiled(bool enable);
-    
+
     /// Return texture.
     /// Return texture.
     Texture* GetTexture() const { return texture_; }
     Texture* GetTexture() const { return texture_; }
     /// Return image rectangle.
     /// Return image rectangle.
@@ -80,16 +80,16 @@ public:
     BlendMode GetBlendMode() const { return blendMode_; }
     BlendMode GetBlendMode() const { return blendMode_; }
     /// Return whether is tiled.
     /// Return whether is tiled.
     bool IsTiled() const { return tiled_; }
     bool IsTiled() const { return tiled_; }
-    
+
     /// Set texture attribute.
     /// Set texture attribute.
-    void SetTextureAttr(ResourceRef value);
+    void SetTextureAttr(const ResourceRef& value);
     /// Return texture attribute.
     /// Return texture attribute.
     ResourceRef GetTextureAttr() const;
     ResourceRef GetTextureAttr() const;
-    
+
 protected:
 protected:
     /// Return UI rendering batches with offset to image rectangle.
     /// Return UI rendering batches with offset to image rectangle.
     void GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor, const IntVector2& offset);
     void GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor, const IntVector2& offset);
-    
+
     /// Texture.
     /// Texture.
     SharedPtr<Texture> texture_;
     SharedPtr<Texture> texture_;
     /// Image rectangle.
     /// Image rectangle.

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

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

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

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

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

@@ -54,14 +54,14 @@ Sprite::~Sprite()
 void Sprite::RegisterObject(Context* context)
 void Sprite::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<Sprite>(UI_CATEGORY);
     context->RegisterFactory<Sprite>(UI_CATEGORY);
-    
+
     REF_ACCESSOR_ATTRIBUTE(Sprite, VAR_STRING, "Name", GetName, SetName, String, String::EMPTY, AM_FILE);
     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_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, "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_INTVECTOR2, "Hotspot", GetHotSpot, SetHotSpot, IntVector2, IntVector2::ZERO, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Sprite, VAR_VECTOR2, "Scale", GetScale, SetScale, Vector2, Vector2::ONE, 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_FLOAT, "Rotation", GetRotation, SetRotation, float, 0.0f, AM_FILE);
-    ACCESSOR_ATTRIBUTE(Sprite, VAR_RESOURCEREF, "Texture", GetTextureAttr, SetTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_FILE);
+    MIXED_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);
     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, "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, "Horiz Alignment", GetHorizontalAlignment, SetHorizontalAlignment, HorizontalAlignment, horizontalAlignments, HA_LEFT, AM_FILE);
@@ -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 ||
     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)
         color_[C_BOTTOMLEFT].a_ < 1.0f || color_[C_BOTTOMRIGHT].a_ < 1.0f)
         allOpaque = false;
         allOpaque = false;
-    
+
     const IntVector2& size = GetSize();
     const IntVector2& size = GetSize();
     UIBatch batch(this, blendMode_ == BLEND_REPLACE && !allOpaque ? BLEND_ALPHA : blendMode_, currentScissor, texture_, &vertexData);
     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_ -
     batch.AddQuad(GetTransform(), 0, 0, size.x_, size.y_, imageRect_.left_, imageRect_.top_, imageRect_.right_ -
         imageRect_.left_, imageRect_.bottom_ - imageRect_.top_);
         imageRect_.left_, imageRect_.bottom_ - imageRect_.top_);
-    
+
     UIBatch::AddOrMerge(batch, batches);
     UIBatch::AddOrMerge(batch, batches);
-    
+
     // Reset hovering for next frame
     // Reset hovering for next frame
     hovering_ = false;
     hovering_ = false;
 }
 }
@@ -203,9 +203,9 @@ const Matrix3x4& Sprite::GetTransform() const
     if (positionDirty_)
     if (positionDirty_)
     {
     {
         Vector2 pos = floatPosition_;
         Vector2 pos = floatPosition_;
-        
+
         Matrix3x4 parentTransform;
         Matrix3x4 parentTransform;
-        
+
         if (parent_)
         if (parent_)
         {
         {
             Sprite* parentSprite = dynamic_cast<Sprite*>(parent_);
             Sprite* parentSprite = dynamic_cast<Sprite*>(parent_);
@@ -217,16 +217,16 @@ const Matrix3x4& Sprite::GetTransform() const
                 parentTransform = Matrix3x4::IDENTITY;
                 parentTransform = Matrix3x4::IDENTITY;
                 parentTransform.SetTranslation(Vector3((float)parentScreenPos.x_, (float)parentScreenPos.y_, 0.0f));
                 parentTransform.SetTranslation(Vector3((float)parentScreenPos.x_, (float)parentScreenPos.y_, 0.0f));
             }
             }
-            
+
             switch (GetHorizontalAlignment())
             switch (GetHorizontalAlignment())
             {
             {
             case HA_LEFT:
             case HA_LEFT:
                 break;
                 break;
-                
+
             case HA_CENTER:
             case HA_CENTER:
                 pos.x_ += (float)(parent_->GetSize().x_ / 2);
                 pos.x_ += (float)(parent_->GetSize().x_ / 2);
                 break;
                 break;
-                
+
             case HA_RIGHT:
             case HA_RIGHT:
                 pos.x_ += (float)parent_->GetSize().x_;
                 pos.x_ += (float)parent_->GetSize().x_;
                 break;
                 break;
@@ -235,11 +235,11 @@ const Matrix3x4& Sprite::GetTransform() const
             {
             {
             case VA_TOP:
             case VA_TOP:
                 break;
                 break;
-                
+
             case VA_CENTER:
             case VA_CENTER:
                 pos.y_ += (float)(parent_->GetSize().y_ / 2);
                 pos.y_ += (float)(parent_->GetSize().y_ / 2);
                 break;
                 break;
-                
+
             case VA_BOTTOM:
             case VA_BOTTOM:
                 pos.y_ += (float)(parent_->GetSize().y_);
                 pos.y_ += (float)(parent_->GetSize().y_);
                 break;
                 break;
@@ -247,24 +247,24 @@ const Matrix3x4& Sprite::GetTransform() const
         }
         }
         else
         else
             parentTransform = Matrix3x4::IDENTITY;
             parentTransform = Matrix3x4::IDENTITY;
-        
+
         Matrix3x4 hotspotAdjust(Matrix3x4::IDENTITY);
         Matrix3x4 hotspotAdjust(Matrix3x4::IDENTITY);
         hotspotAdjust.SetTranslation(Vector3((float)-hotSpot_.x_, (float)-hotSpot_.y_, 0.0f));
         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));
         Matrix3x4 mainTransform(Vector3(pos, 0.0f), Quaternion(rotation_, Vector3::FORWARD), Vector3(scale_, 1.0f));
-        
+
         transform_ = parentTransform * mainTransform * hotspotAdjust;
         transform_ = parentTransform * mainTransform * hotspotAdjust;
         positionDirty_ = false;
         positionDirty_ = false;
-        
+
         // Calculate an approximate screen position for GetElementAt(), or pixel-perfect child elements
         // Calculate an approximate screen position for GetElementAt(), or pixel-perfect child elements
         Vector3 topLeftCorner = transform_ * Vector3::ZERO;
         Vector3 topLeftCorner = transform_ * Vector3::ZERO;
         screenPosition_ = IntVector2((int)topLeftCorner.x_, (int)topLeftCorner.y_);
         screenPosition_ = IntVector2((int)topLeftCorner.x_, (int)topLeftCorner.y_);
     }
     }
-    
+
     return transform_;
     return transform_;
 }
 }
 
 
-void Sprite::SetTextureAttr(ResourceRef value)
+void Sprite::SetTextureAttr(const ResourceRef& value)
 {
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SetTexture(cache->GetResource<Texture2D>(value.name_));
     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
 class URHO3D_API Sprite : public UIElement
 {
 {
     OBJECT(Sprite);
     OBJECT(Sprite);
-    
+
 public:
 public:
     /// Construct.
     /// Construct.
     Sprite(Context* context);
     Sprite(Context* context);
@@ -40,7 +40,7 @@ public:
     virtual ~Sprite();
     virtual ~Sprite();
     /// Register object factory.
     /// Register object factory.
     static void RegisterObject(Context* context);
     static void RegisterObject(Context* context);
-    
+
     /// Return whether is visible and inside a scissor rectangle and should be rendered.
     /// Return whether is visible and inside a scissor rectangle and should be rendered.
     virtual bool IsWithinScissor(const IntRect& currentScissor);
     virtual bool IsWithinScissor(const IntRect& currentScissor);
     /// Update and return screen position.
     /// Update and return screen position.
@@ -49,7 +49,7 @@ public:
     virtual void GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor);
     virtual void GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor);
     /// React to position change.
     /// React to position change.
     virtual void OnPositionSet();
     virtual void OnPositionSet();
-    
+
     /// Set floating point position.
     /// Set floating point position.
     void SetPosition(const Vector2& position);
     void SetPosition(const Vector2& position);
     /// Set floating point position.
     /// Set floating point position.
@@ -74,7 +74,7 @@ public:
     void SetFullImageRect();
     void SetFullImageRect();
     /// Set blend mode.
     /// Set blend mode.
     void SetBlendMode(BlendMode mode);
     void SetBlendMode(BlendMode mode);
-    
+
     /// Return floating point position.
     /// Return floating point position.
     const Vector2& GetPosition() const { return floatPosition_; }
     const Vector2& GetPosition() const { return floatPosition_; }
     /// Return hotspot.
     /// Return hotspot.
@@ -89,14 +89,14 @@ public:
     const IntRect& GetImageRect() const { return imageRect_; }
     const IntRect& GetImageRect() const { return imageRect_; }
     /// Return blend mode.
     /// Return blend mode.
     BlendMode GetBlendMode() const { return blendMode_; }
     BlendMode GetBlendMode() const { return blendMode_; }
-    
+
     /// Set texture attribute.
     /// Set texture attribute.
-    void SetTextureAttr(ResourceRef value);
+    void SetTextureAttr(const ResourceRef& value);
     /// Return texture attribute.
     /// Return texture attribute.
     ResourceRef GetTextureAttr() const;
     ResourceRef GetTextureAttr() const;
     /// Update and return rendering transform, also used to transform child sprites.
     /// Update and return rendering transform, also used to transform child sprites.
     const Matrix3x4& GetTransform() const;
     const Matrix3x4& GetTransform() const;
-    
+
 protected:
 protected:
     /// Floating point position.
     /// Floating point position.
     Vector2 floatPosition_;
     Vector2 floatPosition_;

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

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

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

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

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

@@ -66,10 +66,10 @@ Text3D::~Text3D()
 void Text3D::RegisterObject(Context* context)
 void Text3D::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<Text3D>(GEOMETRY_CATEGORY);
     context->RegisterFactory<Text3D>(GEOMETRY_CATEGORY);
-    
+
     ACCESSOR_ATTRIBUTE(Text3D, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
     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);
+    MIXED_ACCESSOR_ATTRIBUTE(Text3D, VAR_RESOURCEREF, "Font", GetFontAttr, SetFontAttr, ResourceRef, ResourceRef(Font::GetTypeStatic()), AM_DEFAULT);
+    MIXED_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_INT, "Font Size", text_.fontSize_, DEFAULT_FONT_SIZE, AM_DEFAULT);
     ATTRIBUTE(Text3D, VAR_STRING, "Text", text_.text_, String::EMPTY, 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);
     ENUM_ATTRIBUTE(Text3D, "Text Alignment", text_.textAlignment_, horizontalAlignments, HA_LEFT, AM_DEFAULT);
@@ -103,7 +103,7 @@ void Text3D::ApplyAttributes()
 void Text3D::UpdateBatches(const FrameInfo& frame)
 void Text3D::UpdateBatches(const FrameInfo& frame)
 {
 {
     distance_ = frame.camera_->GetDistance(GetWorldBoundingBox().Center());
     distance_ = frame.camera_->GetDistance(GetWorldBoundingBox().Center());
-    
+
     if (faceCameraMode_ != FC_NONE)
     if (faceCameraMode_ != FC_NONE)
     {
     {
         Vector3 worldPosition = node_->GetWorldPosition();
         Vector3 worldPosition = node_->GetWorldPosition();
@@ -111,7 +111,7 @@ void Text3D::UpdateBatches(const FrameInfo& frame)
             worldPosition, node_->GetWorldRotation(), faceCameraMode_), node_->GetWorldScale());
             worldPosition, node_->GetWorldRotation(), faceCameraMode_), node_->GetWorldScale());
         worldBoundingBoxDirty_ = true;
         worldBoundingBoxDirty_ = true;
     }
     }
-    
+
     for (unsigned i = 0; i < batches_.Size(); ++i)
     for (unsigned i = 0; i < batches_.Size(); ++i)
     {
     {
         batches_[i].distance_ = distance_;
         batches_[i].distance_ = distance_;
@@ -130,7 +130,7 @@ void Text3D::UpdateGeometry(const FrameInfo& frame)
                 uiBatches_[i].vertexStart_) / UI_VERTEX_SIZE);
                 uiBatches_[i].vertexStart_) / UI_VERTEX_SIZE);
         }
         }
     }
     }
-    
+
     if ((geometryDirty_ || vertexBuffer_->IsDataLost()) && uiVertexData_.Size())
     if ((geometryDirty_ || vertexBuffer_->IsDataLost()) && uiVertexData_.Size())
     {
     {
         unsigned vertexCount = uiVertexData_.Size() / UI_VERTEX_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_->SetSize(vertexCount, MASK_POSITION | MASK_COLOR | MASK_TEXCOORD1);
         vertexBuffer_->SetData(&uiVertexData_[0]);
         vertexBuffer_->SetData(&uiVertexData_[0]);
     }
     }
-    
+
     geometryDirty_ = false;
     geometryDirty_ = false;
 }
 }
 
 
@@ -153,7 +153,7 @@ UpdateGeometryType Text3D::GetUpdateGeometryType()
 void Text3D::SetMaterial(Material* material)
 void Text3D::SetMaterial(Material* material)
 {
 {
     material_ = material;
     material_ = material;
-    
+
     UpdateTextMaterials(true);
     UpdateTextMaterials(true);
 }
 }
 
 
@@ -166,7 +166,7 @@ bool Text3D::SetFont(const String& fontName, int size)
     MarkTextDirty();
     MarkTextDirty();
     UpdateTextBatches();
     UpdateTextBatches();
     UpdateTextMaterials();
     UpdateTextMaterials();
-    
+
     return success;
     return success;
 }
 }
 
 
@@ -177,14 +177,14 @@ bool Text3D::SetFont(Font* font, int size)
     MarkTextDirty();
     MarkTextDirty();
     UpdateTextBatches();
     UpdateTextBatches();
     UpdateTextMaterials();
     UpdateTextMaterials();
-    
+
     return success;
     return success;
 }
 }
 
 
 void Text3D::SetText(const String& text)
 void Text3D::SetText(const String& text)
 {
 {
     text_.SetText(text);
     text_.SetText(text);
-    
+
     // Changing text requires materials to be re-evaluated, in case the font is multi-page
     // Changing text requires materials to be re-evaluated, in case the font is multi-page
     MarkTextDirty();
     MarkTextDirty();
     UpdateTextBatches();
     UpdateTextBatches();
@@ -194,49 +194,49 @@ void Text3D::SetText(const String& text)
 void Text3D::SetAlignment(HorizontalAlignment hAlign, VerticalAlignment vAlign)
 void Text3D::SetAlignment(HorizontalAlignment hAlign, VerticalAlignment vAlign)
 {
 {
     text_.SetAlignment(hAlign, vAlign);
     text_.SetAlignment(hAlign, vAlign);
-    
+
     MarkTextDirty();
     MarkTextDirty();
 }
 }
 
 
 void Text3D::SetHorizontalAlignment(HorizontalAlignment align)
 void Text3D::SetHorizontalAlignment(HorizontalAlignment align)
 {
 {
     text_.SetHorizontalAlignment(align);
     text_.SetHorizontalAlignment(align);
-    
+
     MarkTextDirty();
     MarkTextDirty();
 }
 }
 
 
 void Text3D::SetVerticalAlignment(VerticalAlignment align)
 void Text3D::SetVerticalAlignment(VerticalAlignment align)
 {
 {
     text_.SetVerticalAlignment(align);
     text_.SetVerticalAlignment(align);
-    
+
     MarkTextDirty();
     MarkTextDirty();
 }
 }
 
 
 void Text3D::SetTextAlignment(HorizontalAlignment align)
 void Text3D::SetTextAlignment(HorizontalAlignment align)
 {
 {
     text_.SetTextAlignment(align);
     text_.SetTextAlignment(align);
-    
+
     MarkTextDirty();
     MarkTextDirty();
 }
 }
 
 
 void Text3D::SetRowSpacing(float spacing)
 void Text3D::SetRowSpacing(float spacing)
 {
 {
     text_.SetRowSpacing(spacing);
     text_.SetRowSpacing(spacing);
-    
+
     MarkTextDirty();
     MarkTextDirty();
 }
 }
 
 
 void Text3D::SetWordwrap(bool enable)
 void Text3D::SetWordwrap(bool enable)
 {
 {
     text_.SetWordwrap(enable);
     text_.SetWordwrap(enable);
-    
+
     MarkTextDirty();
     MarkTextDirty();
 }
 }
 
 
 void Text3D::SetTextEffect(TextEffect textEffect)
 void Text3D::SetTextEffect(TextEffect textEffect)
 {
 {
     text_.SetTextEffect(textEffect);
     text_.SetTextEffect(textEffect);
-    
+
     MarkTextDirty();
     MarkTextDirty();
     UpdateTextMaterials(true);
     UpdateTextMaterials(true);
 }
 }
@@ -244,7 +244,7 @@ void Text3D::SetTextEffect(TextEffect textEffect)
 void Text3D::SetEffectColor(const Color& effectColor)
 void Text3D::SetEffectColor(const Color& effectColor)
 {
 {
     text_.SetEffectColor(effectColor);
     text_.SetEffectColor(effectColor);
-    
+
     MarkTextDirty();
     MarkTextDirty();
     UpdateTextMaterials();
     UpdateTextMaterials();
 }
 }
@@ -252,7 +252,7 @@ void Text3D::SetEffectColor(const Color& effectColor)
 void Text3D::SetEffectDepthBias(float bias)
 void Text3D::SetEffectDepthBias(float bias)
 {
 {
     text_.SetEffectDepthBias(bias);
     text_.SetEffectDepthBias(bias);
-    
+
     MarkTextDirty();
     MarkTextDirty();
 }
 }
 
 
@@ -260,28 +260,28 @@ void Text3D::SetWidth(int width)
 {
 {
     text_.SetMinWidth(width);
     text_.SetMinWidth(width);
     text_.SetWidth(width);
     text_.SetWidth(width);
-    
+
     MarkTextDirty();
     MarkTextDirty();
 }
 }
 
 
 void Text3D::SetColor(const Color& color)
 void Text3D::SetColor(const Color& color)
 {
 {
     text_.SetColor(color);
     text_.SetColor(color);
-    
+
     MarkTextDirty();
     MarkTextDirty();
 }
 }
 
 
 void Text3D::SetColor(Corner corner, const Color& color)
 void Text3D::SetColor(Corner corner, const Color& color)
 {
 {
     text_.SetColor(corner, color);
     text_.SetColor(corner, color);
-    
+
     MarkTextDirty();
     MarkTextDirty();
 }
 }
 
 
 void Text3D::SetOpacity(float opacity)
 void Text3D::SetOpacity(float opacity)
 {
 {
     text_.SetOpacity(opacity);
     text_.SetOpacity(opacity);
-    
+
     MarkTextDirty();
     MarkTextDirty();
 }
 }
 
 
@@ -290,7 +290,7 @@ void Text3D::SetFaceCameraMode(FaceCameraMode mode)
     if (mode != faceCameraMode_)
     if (mode != faceCameraMode_)
     {
     {
         faceCameraMode_ = mode;
         faceCameraMode_ = mode;
-        
+
         // Bounding box must be recalculated
         // Bounding box must be recalculated
         OnMarkedDirty(node_);
         OnMarkedDirty(node_);
     }
     }
@@ -404,7 +404,7 @@ float Text3D::GetOpacity() const
 void Text3D::OnNodeSet(Node* node)
 void Text3D::OnNodeSet(Node* node)
 {
 {
     Drawable::OnNodeSet(node);
     Drawable::OnNodeSet(node);
-    
+
     if (node)
     if (node)
         customWorldTransform_ = node->GetWorldTransform();
         customWorldTransform_ = node->GetWorldTransform();
 }
 }
@@ -413,7 +413,7 @@ void Text3D::OnWorldBoundingBoxUpdate()
 {
 {
     if (textDirty_)
     if (textDirty_)
         UpdateTextBatches();
         UpdateTextBatches();
-    
+
     // In face camera mode, use the last camera rotation to build the world bounding box
     // In face camera mode, use the last camera rotation to build the world bounding box
     worldBoundingBox_ = boundingBox_.Transformed(faceCameraMode_ != FC_NONE ? Matrix3x4(node_->GetWorldPosition(),
     worldBoundingBox_ = boundingBox_.Transformed(faceCameraMode_ != FC_NONE ? Matrix3x4(node_->GetWorldPosition(),
         customWorldTransform_.Rotation(), node_->GetWorldScale()) : node_->GetWorldTransform());
         customWorldTransform_.Rotation(), node_->GetWorldScale()) : node_->GetWorldTransform());
@@ -422,18 +422,18 @@ void Text3D::OnWorldBoundingBoxUpdate()
 void Text3D::MarkTextDirty()
 void Text3D::MarkTextDirty()
 {
 {
     textDirty_ = true;
     textDirty_ = true;
-    
+
     OnMarkedDirty(node_);
     OnMarkedDirty(node_);
     MarkNetworkUpdate();
     MarkNetworkUpdate();
 }
 }
 
 
-void Text3D::SetMaterialAttr(ResourceRef value)
+void Text3D::SetMaterialAttr(const ResourceRef& value)
 {
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SetMaterial(cache->GetResource<Material>(value.name_));
     SetMaterial(cache->GetResource<Material>(value.name_));
 }
 }
 
 
-void Text3D::SetFontAttr(ResourceRef value)
+void Text3D::SetFontAttr(const ResourceRef& value)
 {
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     text_.font_ = cache->GetResource<Font>(value.name_);
     text_.font_ = cache->GetResource<Font>(value.name_);
@@ -453,42 +453,42 @@ void Text3D::UpdateTextBatches()
 {
 {
     uiBatches_.Clear();
     uiBatches_.Clear();
     uiVertexData_.Clear();
     uiVertexData_.Clear();
-    
+
     text_.GetBatches(uiBatches_, uiVertexData_, IntRect::ZERO);
     text_.GetBatches(uiBatches_, uiVertexData_, IntRect::ZERO);
-    
+
     Vector3 offset(Vector3::ZERO);
     Vector3 offset(Vector3::ZERO);
-    
+
     switch (text_.GetHorizontalAlignment())
     switch (text_.GetHorizontalAlignment())
     {
     {
     case HA_LEFT:
     case HA_LEFT:
         break;
         break;
-        
+
     case HA_CENTER:
     case HA_CENTER:
         offset.x_ -= (float)text_.GetWidth() * 0.5f;
         offset.x_ -= (float)text_.GetWidth() * 0.5f;
         break;
         break;
-        
+
     case HA_RIGHT:
     case HA_RIGHT:
         offset.x_ -= (float)text_.GetWidth();
         offset.x_ -= (float)text_.GetWidth();
         break;
         break;
     }
     }
-    
+
     switch (text_.GetVerticalAlignment())
     switch (text_.GetVerticalAlignment())
     {
     {
     case VA_TOP:
     case VA_TOP:
         break;
         break;
-        
+
     case VA_CENTER:
     case VA_CENTER:
         offset.y_ -= (float)text_.GetHeight() * 0.5f;
         offset.y_ -= (float)text_.GetHeight() * 0.5f;
         break;
         break;
-        
+
     case VA_BOTTOM:
     case VA_BOTTOM:
         offset.y_ -= (float)text_.GetHeight();
         offset.y_ -= (float)text_.GetHeight();
         break;
         break;
     }
     }
-    
+
     boundingBox_.defined_ = false;
     boundingBox_.defined_ = false;
     boundingBox_.min_ = boundingBox_.max_ = Vector3::ZERO;
     boundingBox_.min_ = boundingBox_.max_ = Vector3::ZERO;
-    
+
     for (unsigned i = 0; i < uiVertexData_.Size(); i += UI_VERTEX_SIZE)
     for (unsigned i = 0; i < uiVertexData_.Size(); i += UI_VERTEX_SIZE)
     {
     {
         Vector3& position = *(reinterpret_cast<Vector3*>(&uiVertexData_[i]));
         Vector3& position = *(reinterpret_cast<Vector3*>(&uiVertexData_[i]));
@@ -497,7 +497,7 @@ void Text3D::UpdateTextBatches()
         position.y_ = -position.y_;
         position.y_ = -position.y_;
         boundingBox_.Merge(position);
         boundingBox_.Merge(position);
     }
     }
-    
+
     textDirty_ = false;
     textDirty_ = false;
     geometryDirty_ = true;
     geometryDirty_ = true;
 }
 }
@@ -506,7 +506,7 @@ void Text3D::UpdateTextMaterials(bool forceUpdate)
 {
 {
     batches_.Resize(uiBatches_.Size());
     batches_.Resize(uiBatches_.Size());
     geometries_.Resize(uiBatches_.Size());
     geometries_.Resize(uiBatches_.Size());
-    
+
     for (unsigned i = 0; i < batches_.Size(); ++i)
     for (unsigned i = 0; i < batches_.Size(); ++i)
     {
     {
         if (!geometries_[i])
         if (!geometries_[i])
@@ -515,7 +515,7 @@ void Text3D::UpdateTextMaterials(bool forceUpdate)
             geometry->SetVertexBuffer(0, vertexBuffer_, MASK_POSITION | MASK_COLOR | MASK_TEXCOORD1);
             geometry->SetVertexBuffer(0, vertexBuffer_, MASK_POSITION | MASK_COLOR | MASK_TEXCOORD1);
             batches_[i].geometry_ = geometries_[i] = geometry;
             batches_[i].geometry_ = geometries_[i] = geometry;
         }
         }
-        
+
         if (!batches_[i].material_ || forceUpdate)
         if (!batches_[i].material_ || forceUpdate)
         {
         {
             // If material not defined, create a reasonable default from scratch
             // If material not defined, create a reasonable default from scratch
@@ -554,7 +554,7 @@ void Text3D::UpdateTextMaterials(bool forceUpdate)
             else
             else
                 batches_[i].material_ = material_->Clone();
                 batches_[i].material_ = material_->Clone();
         }
         }
-        
+
         Material* material = batches_[i].material_;
         Material* material = batches_[i].material_;
         Texture* texture = uiBatches_[i].texture_;
         Texture* texture = uiBatches_[i].texture_;
         material->SetTexture(TU_DIFFUSE, 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
 class URHO3D_API Text3D : public Drawable
 {
 {
     OBJECT(Text3D);
     OBJECT(Text3D);
-    
+
 public:
 public:
     /// Construct.
     /// Construct.
     Text3D(Context* context);
     Text3D(Context* context);
@@ -44,7 +44,7 @@ public:
     ~Text3D();
     ~Text3D();
     /// Register object factory. Drawable must be registered first.
     /// Register object factory. Drawable must be registered first.
     static void RegisterObject(Context* context);
     static void RegisterObject(Context* context);
-    
+
     /// Apply attribute changes that can not be applied immediately.
     /// Apply attribute changes that can not be applied immediately.
     virtual void ApplyAttributes();
     virtual void ApplyAttributes();
     /// Calculate distance and prepare batches for rendering. May be called from worker thread(s), possibly re-entrantly.
     /// 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);
     virtual void UpdateGeometry(const FrameInfo& frame);
     /// Return whether a geometry update is necessary, and if it can happen in a worker thread.
     /// Return whether a geometry update is necessary, and if it can happen in a worker thread.
     virtual UpdateGeometryType GetUpdateGeometryType();
     virtual UpdateGeometryType GetUpdateGeometryType();
-    
+
     /// Set font and font size and use signed distance field font. Return true if successful.
     /// 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);
     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.
     /// Set font and font size and use signed distance field font. Return true if successful.
@@ -90,7 +90,7 @@ public:
     void SetOpacity(float opacity);
     void SetOpacity(float opacity);
     /// Set how the text should rotate in relation to the camera. Default is to not rotate (FC_NONE.)
     /// Set how the text should rotate in relation to the camera. Default is to not rotate (FC_NONE.)
     void SetFaceCameraMode(FaceCameraMode mode);
     void SetFaceCameraMode(FaceCameraMode mode);
-    
+
     /// Return font.
     /// Return font.
     Font* GetFont() const;
     Font* GetFont() const;
     /// Return material.
     /// Return material.
@@ -135,24 +135,24 @@ public:
     float GetOpacity() const;
     float GetOpacity() const;
     /// Return how the text rotates in relation to the camera.
     /// Return how the text rotates in relation to the camera.
     FaceCameraMode GetFaceCameraMode() const { return faceCameraMode_; }
     FaceCameraMode GetFaceCameraMode() const { return faceCameraMode_; }
-    
+
     /// Set font attribute.
     /// Set font attribute.
-    void SetFontAttr(ResourceRef value);
+    void SetFontAttr(const ResourceRef& value);
     /// Return font attribute.
     /// Return font attribute.
     ResourceRef GetFontAttr() const;
     ResourceRef GetFontAttr() const;
     /// Set material attribute.
     /// Set material attribute.
-    void SetMaterialAttr(ResourceRef value);
+    void SetMaterialAttr(const ResourceRef& value);
     /// Return material attribute.
     /// Return material attribute.
     ResourceRef GetMaterialAttr() const;
     ResourceRef GetMaterialAttr() const;
     /// Get color attribute. Uses just the top-left color.
     /// Get color attribute. Uses just the top-left color.
     const Color& GetColorAttr() const { return text_.color_[0]; }
     const Color& GetColorAttr() const { return text_.color_[0]; }
-    
+
 protected:
 protected:
     /// Handle node being assigned.
     /// Handle node being assigned.
     virtual void OnNodeSet(Node* node);
     virtual void OnNodeSet(Node* node);
     /// Recalculate the world-space bounding box.
     /// Recalculate the world-space bounding box.
     virtual void OnWorldBoundingBoxUpdate();
     virtual void OnWorldBoundingBoxUpdate();
-    
+
 private:
 private:
     /// Mark text & geometry dirty.
     /// Mark text & geometry dirty.
     void MarkTextDirty();
     void MarkTextDirty();
@@ -162,7 +162,7 @@ private:
     void UpdateTextBatches();
     void UpdateTextBatches();
     /// Create materials for text rendering. May only be called from the main thread. Text %UI batches must be up-to-date.
     /// 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);
     void UpdateTextMaterials(bool forceUpdate = false);
-    
+
     /// Internally used text element.
     /// Internally used text element.
     Text text_;
     Text text_;
     /// Geometries.
     /// Geometries.

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

@@ -82,7 +82,7 @@ void AnimatedSprite2D::RegisterObject(Context* context)
     ACCESSOR_ATTRIBUTE(AnimatedSprite2D, VAR_BOOL, "Flip Y", GetFlipY, SetFlipY, 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);
     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_FLOAT, "Speed", GetSpeed, SetSpeed, float, 1.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(AnimatedSprite2D, VAR_RESOURCEREF, "Animation Set", GetAnimationSetAttr, SetAnimationSetAttr, ResourceRef, ResourceRef(AnimatedSprite2D::GetTypeStatic()), AM_DEFAULT);
+    MIXED_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);
     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);
     ENUM_ACCESSOR_ATTRIBUTE(AnimatedSprite2D, "Loop Mode", GetLoopMode, SetLoopMode, LoopMode2D, loopModeNames, LM_DEFAULT, AM_DEFAULT);
     COPY_BASE_ATTRIBUTES(AnimatedSprite2D, Drawable);
     COPY_BASE_ATTRIBUTES(AnimatedSprite2D, Drawable);
@@ -244,7 +244,7 @@ Node* AnimatedSprite2D::GetRootNode() const
     return rootNode_;
     return rootNode_;
 }
 }
 
 
-void AnimatedSprite2D::SetAnimationSetAttr(ResourceRef value)
+void AnimatedSprite2D::SetAnimationSetAttr(const ResourceRef& value)
 {
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SetAnimationSet(cache->GetResource<AnimationSet2D>(value.name_));
     SetAnimationSet(cache->GetResource<AnimationSet2D>(value.name_));

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

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

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

@@ -67,9 +67,9 @@ void Drawable2D::RegisterObject(Context* context)
 {
 {
     ACCESSOR_ATTRIBUTE(Drawable2D, VAR_INT, "Layer", GetLayer, SetLayer, int, 0, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Drawable2D, VAR_INT, "Layer", GetLayer, SetLayer, int, 0, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Drawable2D, VAR_INT, "Order in Layer", GetOrderInLayer, SetOrderInLayer, int, 0, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Drawable2D, VAR_INT, "Order in Layer", GetOrderInLayer, SetOrderInLayer, int, 0, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Drawable2D, VAR_RESOURCEREF, "Sprite", GetSpriteAttr, SetSpriteAttr, ResourceRef, ResourceRef(Sprite2D::GetTypeStatic()), AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE(Drawable2D, VAR_RESOURCEREF, "Sprite", GetSpriteAttr, SetSpriteAttr, ResourceRef, ResourceRef(Sprite2D::GetTypeStatic()), AM_DEFAULT);
     ENUM_ACCESSOR_ATTRIBUTE(Drawable2D, "Blend Mode", GetBlendMode, SetBlendModeAttr, BlendMode, blendModeNames, BLEND_ALPHA, AM_DEFAULT);
     ENUM_ACCESSOR_ATTRIBUTE(Drawable2D, "Blend Mode", GetBlendMode, SetBlendModeAttr, BlendMode, blendModeNames, BLEND_ALPHA, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Drawable2D, VAR_RESOURCEREF, "Material", GetMaterialAttr, SetMaterialAttr, ResourceRef, ResourceRef(Material::GetTypeStatic()), AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE(Drawable2D, VAR_RESOURCEREF, "Material", GetMaterialAttr, SetMaterialAttr, ResourceRef, ResourceRef(Material::GetTypeStatic()), AM_DEFAULT);
     COPY_BASE_ATTRIBUTES(Drawable2D, Drawable);
     COPY_BASE_ATTRIBUTES(Drawable2D, Drawable);
 }
 }
 
 
@@ -173,7 +173,7 @@ const Vector<Vertex2D>& Drawable2D::GetVertices()
     return vertices_;
     return vertices_;
 }
 }
 
 
-void Drawable2D::SetSpriteAttr(ResourceRef value)
+void Drawable2D::SetSpriteAttr(const ResourceRef& value)
 {
 {
     // Delay applying material update
     // Delay applying material update
     materialUpdatePending_ = true;
     materialUpdatePending_ = true;
@@ -225,7 +225,7 @@ void Drawable2D::SetBlendModeAttr(BlendMode mode)
     SetBlendMode(mode);
     SetBlendMode(mode);
 }
 }
 
 
-void Drawable2D::SetMaterialAttr(ResourceRef value)
+void Drawable2D::SetMaterialAttr(const ResourceRef& value)
 {
 {
     // Delay applying material update
     // Delay applying material update
     materialUpdatePending_ = true;
     materialUpdatePending_ = true;

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

@@ -88,13 +88,13 @@ public:
     bool GetVisibility() const { return visibility_; }
     bool GetVisibility() const { return visibility_; }
 
 
     /// Set sprite attribute.
     /// Set sprite attribute.
-    void SetSpriteAttr(ResourceRef value);
+    void SetSpriteAttr(const ResourceRef& value);
     /// Return sprite attribute.
     /// Return sprite attribute.
     ResourceRef GetSpriteAttr() const;
     ResourceRef GetSpriteAttr() const;
     /// Set blend mode attribute.
     /// Set blend mode attribute.
     void SetBlendModeAttr(BlendMode mode);
     void SetBlendModeAttr(BlendMode mode);
     /// Set material attribute.
     /// Set material attribute.
-    void SetMaterialAttr(ResourceRef value);
+    void SetMaterialAttr(const ResourceRef& value);
     /// Return material attribute.
     /// Return material attribute.
     ResourceRef GetMaterialAttr() const;
     ResourceRef GetMaterialAttr() const;
 
 

+ 11 - 11
Source/Engine/Urho2D/ParticleEmitter2D.cpp

@@ -38,7 +38,7 @@ extern const char* URHO2D_CATEGORY;
 
 
 ParticleEmitter2D::ParticleEmitter2D(Context* context) :
 ParticleEmitter2D::ParticleEmitter2D(Context* context) :
     Drawable2D(context),
     Drawable2D(context),
-    numParticles_(0), 
+    numParticles_(0),
     emissionTime_(0.0f),
     emissionTime_(0.0f),
     emitParticleTime_(0.0f),
     emitParticleTime_(0.0f),
     boundingBoxMinPoint_(Vector3::ZERO),
     boundingBoxMinPoint_(Vector3::ZERO),
@@ -54,7 +54,7 @@ void ParticleEmitter2D::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<ParticleEmitter2D>(URHO2D_CATEGORY);
     context->RegisterFactory<ParticleEmitter2D>(URHO2D_CATEGORY);
 
 
-    ACCESSOR_ATTRIBUTE(ParticleEmitter2D, VAR_RESOURCEREF, "Particle Effect", GetParticleEffectAttr, SetParticleEffectAttr, ResourceRef, ResourceRef(ParticleEffect2D::GetTypeStatic()), AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE(ParticleEmitter2D, VAR_RESOURCEREF, "Particle Effect", GetParticleEffectAttr, SetParticleEffectAttr, ResourceRef, ResourceRef(ParticleEffect2D::GetTypeStatic()), AM_DEFAULT);
     COPY_BASE_ATTRIBUTES(ParticleEmitter2D, Drawable2D);
     COPY_BASE_ATTRIBUTES(ParticleEmitter2D, Drawable2D);
 }
 }
 
 
@@ -104,7 +104,7 @@ void ParticleEmitter2D::Update(const FrameInfo& frame)
     if (emissionTime_ >= 0.0f)
     if (emissionTime_ >= 0.0f)
     {
     {
         float worldAngle = GetNode()->GetWorldRotation().RollAngle();
         float worldAngle = GetNode()->GetWorldRotation().RollAngle();
-        
+
         float timeBetweenParticles = effect_->GetParticleLifeSpan() / particles_.Size();
         float timeBetweenParticles = effect_->GetParticleLifeSpan() / particles_.Size();
         emitParticleTime_ += timeStep;
         emitParticleTime_ += timeStep;
 
 
@@ -122,7 +122,7 @@ void ParticleEmitter2D::Update(const FrameInfo& frame)
 
 
     verticesDirty_ = true;
     verticesDirty_ = true;
     OnMarkedDirty(node_);
     OnMarkedDirty(node_);
-   
+
 }
 }
 
 
 void ParticleEmitter2D::SetEffect(ParticleEffect2D* model)
 void ParticleEmitter2D::SetEffect(ParticleEffect2D* model)
@@ -147,7 +147,7 @@ void ParticleEmitter2D::SetEffect(ParticleEffect2D* model)
 void ParticleEmitter2D::SetMaxParticles(unsigned maxParticles)
 void ParticleEmitter2D::SetMaxParticles(unsigned maxParticles)
 {
 {
     maxParticles = Max(maxParticles, 1);
     maxParticles = Max(maxParticles, 1);
-    
+
     particles_.Resize(maxParticles);
     particles_.Resize(maxParticles);
     vertices_.Reserve(maxParticles * 4);
     vertices_.Reserve(maxParticles * 4);
 
 
@@ -159,10 +159,10 @@ ParticleEffect2D* ParticleEmitter2D::GetEffect() const
     return effect_;
     return effect_;
 }
 }
 
 
-void ParticleEmitter2D::SetParticleEffectAttr(ResourceRef value)
+void ParticleEmitter2D::SetParticleEffectAttr(const ResourceRef& value)
 {
 {
     materialUpdatePending_ = true;
     materialUpdatePending_ = true;
-    
+
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SetEffect(cache->GetResource<ParticleEffect2D>(value.name_));
     SetEffect(cache->GetResource<ParticleEffect2D>(value.name_));
 }
 }
@@ -222,7 +222,7 @@ void ParticleEmitter2D::UpdateVertices()
     for (int i = 0; i < numParticles_; ++i)
     for (int i = 0; i < numParticles_; ++i)
     {
     {
         Particle2D& p = particles_[i];
         Particle2D& p = particles_[i];
-        
+
         float rotation = -p.rotation_;
         float rotation = -p.rotation_;
         float c = Cos(rotation);
         float c = Cos(rotation);
         float s = Sin(rotation);
         float s = Sin(rotation);
@@ -233,7 +233,7 @@ void ParticleEmitter2D::UpdateVertices()
         vertex1.position_ = Vector3(p.position_.x_ - add, p.position_.y_ + sub, 0.0f);
         vertex1.position_ = Vector3(p.position_.x_ - add, p.position_.y_ + sub, 0.0f);
         vertex2.position_ = Vector3(p.position_.x_ + sub, p.position_.y_ + add, 0.0f);
         vertex2.position_ = Vector3(p.position_.x_ + sub, p.position_.y_ + add, 0.0f);
         vertex3.position_ = Vector3(p.position_.x_ + add, p.position_.y_ - sub, 0.0f);
         vertex3.position_ = Vector3(p.position_.x_ + add, p.position_.y_ - sub, 0.0f);
-        
+
         vertex0.color_ = vertex1.color_ = vertex2.color_  = vertex3.color_ = p.color_.ToUInt();
         vertex0.color_ = vertex1.color_ = vertex2.color_  = vertex3.color_ = p.color_.ToUInt();
 
 
         vertices_.Push(vertex0);
         vertices_.Push(vertex0);
@@ -303,7 +303,7 @@ void ParticleEmitter2D::UpdateParticle(Particle2D& particle, float timeStep, con
 {
 {
     if (timeStep > particle.timeToLive_)
     if (timeStep > particle.timeToLive_)
         timeStep = particle.timeToLive_;
         timeStep = particle.timeToLive_;
-    
+
     particle.timeToLive_ -= timeStep;
     particle.timeToLive_ -= timeStep;
 
 
     if (effect_->GetEmitterType() == EMITTER_TYPE_RADIAL)
     if (effect_->GetEmitterType() == EMITTER_TYPE_RADIAL)
@@ -318,7 +318,7 @@ void ParticleEmitter2D::UpdateParticle(Particle2D& particle, float timeStep, con
     {
     {
         float distanceX = particle.position_.x_ - particle.startPos_.x_;
         float distanceX = particle.position_.x_ - particle.startPos_.x_;
         float distanceY = particle.position_.y_ - particle.startPos_.y_;
         float distanceY = particle.position_.y_ - particle.startPos_.y_;
-        
+
         float distanceScalar = Vector2(distanceX, distanceY).Length();
         float distanceScalar = Vector2(distanceX, distanceY).Length();
         if (distanceScalar < 0.0001f)
         if (distanceScalar < 0.0001f)
             distanceScalar = 0.0001f;
             distanceScalar = 0.0001f;

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

@@ -34,7 +34,7 @@ class ParticleEffect2D;
 {
 {
     /// Time to live.
     /// Time to live.
     float timeToLive_;
     float timeToLive_;
-    
+
     /// Position.
     /// Position.
     Vector2 position_;
     Vector2 position_;
     /// Size.
     /// Size.
@@ -99,7 +99,7 @@ public:
     unsigned GetMaxParticles() const { return particles_.Size(); }
     unsigned GetMaxParticles() const { return particles_.Size(); }
 
 
     /// Set particle model attr.
     /// Set particle model attr.
-    void SetParticleEffectAttr(ResourceRef value);
+    void SetParticleEffectAttr(const ResourceRef& value);
     /// Return particle model attr.
     /// Return particle model attr.
     ResourceRef GetParticleEffectAttr() const;
     ResourceRef GetParticleEffectAttr() const;
 
 

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

@@ -78,7 +78,7 @@ void RigidBody2D::RegisterObject(Context* context)
     ENUM_ACCESSOR_ATTRIBUTE(RigidBody2D, "Body Type", GetBodyType, SetBodyType, BodyType2D, bodyTypeNames, DEFAULT_BODYTYPE, AM_DEFAULT);
     ENUM_ACCESSOR_ATTRIBUTE(RigidBody2D, "Body Type", GetBodyType, SetBodyType, BodyType2D, bodyTypeNames, DEFAULT_BODYTYPE, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(RigidBody2D, VAR_FLOAT, "Mass", GetMass, SetMass, float, 0.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(RigidBody2D, VAR_FLOAT, "Mass", GetMass, SetMass, float, 0.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(RigidBody2D, VAR_FLOAT, "Inertia", GetInertia, SetInertia, float, 0.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(RigidBody2D, VAR_FLOAT, "Inertia", GetInertia, SetInertia, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(RigidBody2D, VAR_VECTOR2, "Mass Center", GetMassCenter, SetMassCenter, Vector2, Vector2::ZERO, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE(RigidBody2D, VAR_VECTOR2, "Mass Center", GetMassCenter, SetMassCenter, Vector2, Vector2::ZERO, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(RigidBody2D, VAR_BOOL, "Use Fixture Mass", GetUseFixtureMass, SetUseFixtureMass, bool, true, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(RigidBody2D, VAR_BOOL, "Use Fixture Mass", GetUseFixtureMass, SetUseFixtureMass, bool, true, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(RigidBody2D, VAR_FLOAT, "Linear Damping", GetLinearDamping, SetLinearDamping, float, 0.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(RigidBody2D, VAR_FLOAT, "Linear Damping", GetLinearDamping, SetLinearDamping, float, 0.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(RigidBody2D, VAR_FLOAT, "Angular Damping", GetAngularDamping, SetAngularDamping, float, 0.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(RigidBody2D, VAR_FLOAT, "Angular Damping", GetAngularDamping, SetAngularDamping, float, 0.0f, AM_DEFAULT);
@@ -87,7 +87,7 @@ void RigidBody2D::RegisterObject(Context* context)
     ACCESSOR_ATTRIBUTE(RigidBody2D, VAR_BOOL, "Bullet", IsBullet, SetBullet, bool, false, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(RigidBody2D, VAR_BOOL, "Bullet", IsBullet, SetBullet, bool, false, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(RigidBody2D, VAR_FLOAT, "Gravity Scale", GetGravityScale, SetGravityScale, float, 1.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(RigidBody2D, VAR_FLOAT, "Gravity Scale", GetGravityScale, SetGravityScale, float, 1.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(RigidBody2D, VAR_BOOL, "Awake", IsAwake, SetAwake, bool, true, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(RigidBody2D, VAR_BOOL, "Awake", IsAwake, SetAwake, bool, true, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(RigidBody2D, VAR_VECTOR2, "Linear Velocity", GetLinearVelocity, SetLinearVelocity, Vector2, Vector2::ZERO, AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE(RigidBody2D, VAR_VECTOR2, "Linear Velocity", GetLinearVelocity, SetLinearVelocity, Vector2, Vector2::ZERO, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(RigidBody2D, VAR_FLOAT, "Angular Velocity", GetAngularVelocity, SetAngularVelocity, float, 0.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(RigidBody2D, VAR_FLOAT, "Angular Velocity", GetAngularVelocity, SetAngularVelocity, float, 0.0f, AM_DEFAULT);
 
 
     COPY_BASE_ATTRIBUTES(RigidBody2D, Component);
     COPY_BASE_ATTRIBUTES(RigidBody2D, Component);
@@ -148,7 +148,7 @@ void RigidBody2D::SetInertia(float inertia)
     MarkNetworkUpdate();
     MarkNetworkUpdate();
 }
 }
 
 
-void RigidBody2D::SetMassCenter(Vector2 center)
+void RigidBody2D::SetMassCenter(const Vector2& center)
 {
 {
     b2Vec2 b2Center = ToB2Vec2(center);
     b2Vec2 b2Center = ToB2Vec2(center);
     if (massData_.center == b2Center)
     if (massData_.center == b2Center)
@@ -271,7 +271,7 @@ void RigidBody2D::SetAwake(bool awake)
     MarkNetworkUpdate();
     MarkNetworkUpdate();
 }
 }
 
 
-void RigidBody2D::SetLinearVelocity(Vector2 linearVelocity)
+void RigidBody2D::SetLinearVelocity(const Vector2& linearVelocity)
 {
 {
     b2Vec2 b2linearVelocity = ToB2Vec2(linearVelocity);
     b2Vec2 b2linearVelocity = ToB2Vec2(linearVelocity);
     if (bodyDef_.linearVelocity == b2linearVelocity)
     if (bodyDef_.linearVelocity == b2linearVelocity)
@@ -486,7 +486,7 @@ void RigidBody2D::OnNodeSet(Node* node)
         node->AddListener(this);
         node->AddListener(this);
         Scene* scene = GetScene();
         Scene* scene = GetScene();
         physicsWorld_ = scene->GetOrCreateComponent<PhysicsWorld2D>();
         physicsWorld_ = scene->GetOrCreateComponent<PhysicsWorld2D>();
-        
+
         CreateBody();
         CreateBody();
         physicsWorld_->AddRigidBody(this);
         physicsWorld_->AddRigidBody(this);
     }
     }

+ 4 - 4
Source/Engine/Urho2D/RigidBody2D.h

@@ -63,7 +63,7 @@ public:
     /// Set inertia.
     /// Set inertia.
     void SetInertia(float inertia);
     void SetInertia(float inertia);
     /// Set mass center.
     /// Set mass center.
-    void SetMassCenter(Vector2 center);
+    void SetMassCenter(const Vector2& center);
     /// Use fixture mass (default is true).
     /// Use fixture mass (default is true).
     void SetUseFixtureMass(bool useFixtureMass);
     void SetUseFixtureMass(bool useFixtureMass);
     /// Set linear damping.
     /// Set linear damping.
@@ -81,7 +81,7 @@ public:
     /// Set awake.
     /// Set awake.
     void SetAwake(bool awake);
     void SetAwake(bool awake);
     /// Set linear velocity.
     /// Set linear velocity.
-    void SetLinearVelocity(Vector2 linearVelocity);
+    void SetLinearVelocity(const Vector2& linearVelocity);
     /// Set angular velocity.
     /// Set angular velocity.
     void SetAngularVelocity(float angularVelocity);
     void SetAngularVelocity(float angularVelocity);
     /// Apply force.
     /// Apply force.
@@ -99,7 +99,7 @@ public:
     void CreateBody();
     void CreateBody();
     /// Release body.
     /// Release body.
     void ReleaseBody();
     void ReleaseBody();
-    
+
     /// Apply world transform.
     /// Apply world transform.
     void ApplyWorldTransform();
     void ApplyWorldTransform();
     /// Add collision shape.
     /// Add collision shape.
@@ -156,7 +156,7 @@ private:
     /// Box2D mass data.
     /// Box2D mass data.
     b2MassData massData_;
     b2MassData massData_;
     /// Use fixture mass.
     /// Use fixture mass.
-    bool useFixtureMass_; 
+    bool useFixtureMass_;
     /// Box2D body.
     /// Box2D body.
     b2Body* body_;
     b2Body* body_;
     /// Collision shapes.
     /// Collision shapes.

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

@@ -50,7 +50,7 @@ TileMap2D::~TileMap2D()
 void TileMap2D::RegisterObject(Context* context)
 void TileMap2D::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<TileMap2D>(URHO2D_CATEGORY);
     context->RegisterFactory<TileMap2D>(URHO2D_CATEGORY);
-    ACCESSOR_ATTRIBUTE(TileMap2D, VAR_RESOURCEREF, "Tmx File", GetTmxFileAttr, SetTmxFileAttr, ResourceRef, ResourceRef(TmxFile2D::GetTypeStatic()), AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE(TileMap2D, VAR_RESOURCEREF, "Tmx File", GetTmxFileAttr, SetTmxFileAttr, ResourceRef, ResourceRef(TmxFile2D::GetTypeStatic()), AM_DEFAULT);
 }
 }
 
 
 void TileMap2D::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
 void TileMap2D::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
@@ -159,7 +159,7 @@ bool TileMap2D::PositionToTileIndex(int& x, int& y, const Vector2& position) con
     return info_.PositionToTileIndex(x, y, position);
     return info_.PositionToTileIndex(x, y, position);
 }
 }
 
 
-void TileMap2D::SetTmxFileAttr(ResourceRef value)
+void TileMap2D::SetTmxFileAttr(const ResourceRef& value)
 {
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SetTmxFile(cache->GetResource<TmxFile2D>(value.name_));
     SetTmxFile(cache->GetResource<TmxFile2D>(value.name_));

+ 1 - 1
Source/Engine/Urho2D/TileMap2D.h

@@ -66,7 +66,7 @@ public:
     bool PositionToTileIndex(int& x, int& y, const Vector2& position) const;
     bool PositionToTileIndex(int& x, int& y, const Vector2& position) const;
 
 
     /// Set tile map file attribute.
     /// Set tile map file attribute.
-    void SetTmxFileAttr(ResourceRef value);
+    void SetTmxFileAttr(const ResourceRef& value);
     /// Return tile map file attribute.
     /// Return tile map file attribute.
     ResourceRef GetTmxFileAttr() const;
     ResourceRef GetTmxFileAttr() const;
 
 

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