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

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

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

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

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

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

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

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

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

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

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

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

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

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

+ 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 Override Flags", viewOverrideFlags_, VO_NONE, AM_DEFAULT);
     REF_ACCESSOR_ATTRIBUTE(Camera, VAR_VECTOR2, "Projection Offset", GetProjectionOffset, SetProjectionOffset, Vector2, Vector2::ZERO, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Camera, VAR_VECTOR4, "Reflection Plane", GetReflectionPlaneAttr, SetReflectionPlaneAttr, Vector4, Vector4(0.0f, 1.0f, 0.0f, 0.0f), AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Camera, VAR_VECTOR4, "Clip Plane", GetClipPlaneAttr, SetClipPlaneAttr, Vector4, Vector4(0.0f, 1.0f, 0.0f, 0.0f), AM_DEFAULT);
+    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 Clipping", GetUseClipping, SetUseClipping, bool, false, AM_DEFAULT);
 }
@@ -263,7 +263,7 @@ float Camera::GetNearClip() const
 Frustum Camera::GetSplitFrustum(float nearClip, float farClip) const
 {
     Frustum ret;
-    
+
     Matrix3x4 worldTransform = GetEffectiveWorldTransform();
     nearClip = Max(nearClip, GetNearClip());
     farClip = Min(farClip, farClip_);
@@ -365,7 +365,7 @@ const Frustum& Camera::GetFrustum() const
     if (frustumDirty_)
     {
         Matrix3x4 worldTransform = GetEffectiveWorldTransform();
-        
+
         if (!orthographic_)
             frustum_.Define(fov_, aspectRatio_, zoom_, GetNearClip(), farClip_, worldTransform);
         else
@@ -531,39 +531,39 @@ Quaternion Camera::GetFaceCameraRotation(const Vector3& position, const Quaterni
 {
     if (!node_)
         return rotation;
-    
+
     switch (mode)
     {
     default:
         return rotation;
-        
+
     case FC_ROTATE_XYZ:
         return node_->GetWorldRotation();
-        
+
     case FC_ROTATE_Y:
         {
             Vector3 euler = rotation.EulerAngles();
             euler.y_ = node_->GetWorldRotation().EulerAngles().y_;
             return Quaternion(euler.x_, euler.y_, euler.z_);
         }
-        
+
     case FC_LOOKAT_XYZ:
         {
             Quaternion lookAt;
             lookAt.FromLookRotation(position - node_->GetWorldPosition());
             return lookAt;
         }
-        
+
     case FC_LOOKAT_Y:
         {
             // Make the Y-only lookat happen on an XZ plane to make sure there are no unwanted transitions
             // or singularities
             Vector3 lookAtVec(position - node_->GetWorldPosition());
             lookAtVec.y_ = 0.0f;
-            
+
             Quaternion lookAt;
             lookAt.FromLookRotation(lookAtVec);
-            
+
             Vector3 euler = rotation.EulerAngles();
             euler.y_ = lookAt.EulerAngles().y_;
             return Quaternion(euler.x_, euler.y_, euler.z_);
@@ -590,7 +590,7 @@ const Matrix3x4& Camera::GetView() const
         view_ = GetEffectiveWorldTransform().Inverse();
         viewDirty_ = false;
     }
-    
+
     return view_;
 }
 
@@ -602,12 +602,12 @@ void Camera::SetAspectRatioInternal(float aspectRatio)
     MarkNetworkUpdate();
 }
 
-void Camera::SetReflectionPlaneAttr(Vector4 value)
+void Camera::SetReflectionPlaneAttr(const Vector4& value)
 {
     SetReflectionPlane(Plane(value));
 }
 
-void Camera::SetClipPlaneAttr(Vector4 value)
+void Camera::SetClipPlaneAttr(const Vector4& value)
 {
     SetClipPlane(Plane(value));
 }

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

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

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

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

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

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

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

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

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

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

+ 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, "Spot FOV", GetFov, SetFov, float, DEFAULT_LIGHT_FOV, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Spot Aspect Ratio", GetAspectRatio, SetAspectRatio, float, 1.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Light, VAR_RESOURCEREF, "Attenuation Texture", GetRampTextureAttr, SetRampTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Light, VAR_RESOURCEREF, "Light Shape Texture", GetShapeTextureAttr, SetShapeTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_DEFAULT);
+    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);
     ATTRIBUTE(Light, VAR_BOOL, "Cast Shadows", castShadows_, 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)
 {
     Color color = GetEffectiveColor();
-    
+
     if (debug && IsEnabledEffective())
     {
         switch (lightType_)
@@ -390,7 +390,7 @@ Frustum Light::GetFrustum() const
 int Light::GetNumShadowSplits() const
 {
     int ret = 1;
-    
+
     if (shadowCascade_.splits_[1] > shadowCascade_.splits_[0])
     {
         ++ret;
@@ -401,7 +401,7 @@ int Light::GetNumShadowSplits() const
                 ++ret;
         }
     }
-    
+
     ret = Min(ret, MAX_CASCADE_SPLITS);
     // Shader Model 2 can only support 3 splits max. due to pixel shader instruction count limits
     if (ret == 4)
@@ -410,7 +410,7 @@ int Light::GetNumShadowSplits() const
         if (graphics && !graphics->GetSM3Support())
             --ret;
     }
-    
+
     return ret;
 }
 
@@ -441,7 +441,7 @@ const Matrix3x4& Light::GetVolumeTransform(Camera* camera)
 {
     if (!node_)
         return Matrix3x4::IDENTITY;
-    
+
     switch (lightType_)
     {
     case LIGHT_DIRECTIONAL:
@@ -464,13 +464,13 @@ const Matrix3x4& Light::GetVolumeTransform(Camera* camera)
     return volumeTransform_;
 }
 
-void Light::SetRampTextureAttr(ResourceRef value)
+void Light::SetRampTextureAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     rampTexture_ = static_cast<Texture*>(cache->GetResource(value.type_, value.name_));
 }
 
-void Light::SetShapeTextureAttr(ResourceRef value)
+void Light::SetShapeTextureAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     shapeTexture_ = static_cast<Texture*>(cache->GetResource(value.type_, value.name_));

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

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

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

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

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

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

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

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

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

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

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

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

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

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

+ 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, "Ambient Gradient", ambientGradient_, false, AM_DEFAULT);
     ATTRIBUTE(Zone, VAR_INT, "Priority", priority_, 0, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Zone, VAR_RESOURCEREF, "Zone Texture", GetZoneTextureAttr, SetZoneTextureAttr, ResourceRef, ResourceRef(TextureCube::GetTypeStatic()), AM_DEFAULT);
+    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, "Shadow Mask", shadowMask_, DEFAULT_SHADOWMASK, 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;
 }
 
-void Zone::SetZoneTextureAttr(ResourceRef value)
+void Zone::SetZoneTextureAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     zoneTexture_ = static_cast<Texture*>(cache->GetResource(value.type_, value.name_));
@@ -247,10 +247,10 @@ void Zone::OnMarkedDirty(Node* node)
     }
 
     Drawable::OnMarkedDirty(node);
-    
+
     // Clear zone reference from all drawables inside the bounding box, and mark gradient dirty in neighbor zones
     ClearDrawablesZone();
-    
+
     inverseWorldDirty_ = true;
 }
 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@@ -132,7 +132,7 @@ public:
     {
         const Vector<PODVector<CustomGeometryVertex> >& srcVertices = custom->GetVertices();
         unsigned totalVertexCount = 0;
-        
+
         for (unsigned i = 0; i < srcVertices.Size(); ++i)
             totalVertexCount += srcVertices[i].Size();
 
@@ -143,11 +143,11 @@ public:
             SharedArrayPtr<unsigned char> indexData(new unsigned char[totalVertexCount * sizeof(unsigned)]);
             dataArrays_.Push(vertexData);
             dataArrays_.Push(indexData);
-            
+
             Vector3* destVertex = reinterpret_cast<Vector3*>(&vertexData[0]);
             unsigned* destIndex = reinterpret_cast<unsigned*>(&indexData[0]);
             unsigned k = 0;
-            
+
             for (unsigned i = 0; i < srcVertices.Size(); ++i)
             {
                 for (unsigned j = 0; j < srcVertices[i].Size(); ++j)
@@ -156,7 +156,7 @@ public:
                     *destIndex++ = k++;
                 }
             }
-            
+
             btIndexedMesh meshIndex;
             meshIndex.m_numTriangles = totalVertexCount / 3;
             meshIndex.m_triangleIndexBase = indexData;
@@ -169,7 +169,7 @@ public:
             m_indexedMeshes.push_back(meshIndex);
         }
     }
-    
+
 private:
     /// Shared vertex/index data used in the collision
     Vector<SharedArrayPtr<unsigned char> > dataArrays_;
@@ -262,7 +262,7 @@ ConvexData::ConvexData(CustomGeometry* custom)
         for (unsigned j = 0; j < srcVertices[i].Size(); ++j)
             vertices.Push(srcVertices[i][j].position_);
     }
-    
+
     BuildHull(vertices);
 }
 
@@ -388,7 +388,7 @@ void CollisionShape::RegisterObject(Context* context)
     ATTRIBUTE(CollisionShape, VAR_VECTOR3, "Size", size_, Vector3::ONE, AM_DEFAULT);
     REF_ACCESSOR_ATTRIBUTE(CollisionShape, VAR_VECTOR3, "Offset Position", GetPosition, SetPosition, Vector3, Vector3::ZERO, AM_DEFAULT);
     REF_ACCESSOR_ATTRIBUTE(CollisionShape, VAR_QUATERNION, "Offset Rotation", GetRotation, SetRotation, Quaternion, Quaternion::IDENTITY, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(CollisionShape, VAR_RESOURCEREF, "Model", GetModelAttr, SetModelAttr, ResourceRef, ResourceRef(Model::GetTypeStatic()), AM_DEFAULT);
+    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_FLOAT, "Collision Margin", margin_, DEFAULT_COLLISION_MARGIN, AM_DEFAULT);
     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>();
     model_ = cache->GetResource<Model>(value.name_);

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

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

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

@@ -179,7 +179,7 @@ void PhysicsWorld::RegisterObject(Context* context)
 {
     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, "Max Substeps", maxSubSteps_, 0, 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::Update(float timeStep)
@@ -242,7 +242,7 @@ void PhysicsWorld::Update(float timeStep)
     }
     else if (maxSubSteps_ > 0)
         maxSubSteps = Min(maxSubSteps, maxSubSteps_);
-    
+
     delayedWorldTransforms_.Clear();
 
     if (interpolation_)
@@ -284,14 +284,14 @@ void PhysicsWorld::UpdateCollisions()
 void PhysicsWorld::SetFps(int fps)
 {
     fps_ = Clamp(fps, 1, 1000);
-    
+
     MarkNetworkUpdate();
 }
 
-void PhysicsWorld::SetGravity(Vector3 gravity)
+void PhysicsWorld::SetGravity(const Vector3& gravity)
 {
     world_->setGravity(ToBtVector3(gravity));
-    
+
     MarkNetworkUpdate();
 }
 
@@ -305,7 +305,7 @@ void PhysicsWorld::SetNumIterations(int num)
 {
     num = Clamp(num, 1, MAX_SOLVER_ITERATIONS);
     world_->getSolverInfo().m_numIterations = num;
-    
+
     MarkNetworkUpdate();
 }
 
@@ -317,21 +317,21 @@ void PhysicsWorld::SetInterpolation(bool enable)
 void PhysicsWorld::SetInternalEdge(bool enable)
 {
     internalEdge_ = enable;
-    
+
     MarkNetworkUpdate();
 }
 
 void PhysicsWorld::SetSplitImpulse(bool enable)
 {
     world_->getSolverInfo().m_splitImpulse = enable;
-    
+
     MarkNetworkUpdate();
 }
 
 void PhysicsWorld::SetMaxNetworkAngularVelocity(float velocity)
 {
     maxNetworkAngularVelocity_ = Clamp(velocity, 1.0f, 32767.0f);
-    
+
     MarkNetworkUpdate();
 }
 
@@ -427,7 +427,7 @@ void PhysicsWorld::ConvexCast(PhysicsRaycastResult& result, CollisionShape* shap
         result.distance_ = M_INFINITY;
         return;
     }
-    
+
     // If shape is attached in a rigidbody, set its collision group temporarily to 0 to make sure it is not returned in the sweep result
     RigidBody* bodyComp = shape->GetComponent<RigidBody>();
     btRigidBody* body = bodyComp ? bodyComp->GetBody() : (btRigidBody*)0;
@@ -457,7 +457,7 @@ void PhysicsWorld::ConvexCast(PhysicsRaycastResult& result, btCollisionShape* sh
         result.distance_ = M_INFINITY;
         return;
     }
-    
+
     if (!shape->isConvex())
     {
         LOGERROR("Can not use non-convex collision shape for convex cast");
@@ -467,7 +467,7 @@ void PhysicsWorld::ConvexCast(PhysicsRaycastResult& result, btCollisionShape* sh
         result.distance_ = M_INFINITY;
         return;
     }
-    
+
     PROFILE(PhysicsConvexCast);
 
     btCollisionWorld::ClosestConvexResultCallback convexCallback(ToBtVector3(startPos), ToBtVector3(endPos));
@@ -715,7 +715,7 @@ void PhysicsWorld::SendCollisionEvents()
     currentCollisions_.Clear();
     physicsCollisionData_.Clear();
     nodeCollisionData_.Clear();
-    
+
     int numManifolds = collisionDispatcher_->getNumManifolds();
 
     if (numManifolds)

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

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

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

@@ -103,17 +103,17 @@ void RigidBody::RegisterObject(Context* context)
     context->RegisterFactory<RigidBody>(PHYSICS_CATEGORY);
 
     ACCESSOR_ATTRIBUTE(RigidBody, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(RigidBody, VAR_QUATERNION, "Physics Rotation", GetRotation, SetRotation, Quaternion, Quaternion::IDENTITY, AM_FILE | AM_NOEDIT);
-    ACCESSOR_ATTRIBUTE(RigidBody, VAR_VECTOR3, "Physics Position", GetPosition, SetPosition, Vector3, Vector3::ZERO, AM_FILE | AM_NOEDIT);
+    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);
     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, "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, "Angular Damping", GetAngularDamping, SetAngularDamping, float, 0.0f, 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_)
     {
@@ -245,7 +245,7 @@ void RigidBody::SetPosition(Vector3 position)
     }
 }
 
-void RigidBody::SetRotation(Quaternion rotation)
+void RigidBody::SetRotation(const Quaternion& rotation)
 {
     if (body_)
     {
@@ -286,7 +286,7 @@ void RigidBody::SetTransform(const Vector3& position, const Quaternion& rotation
     }
 }
 
-void RigidBody::SetLinearVelocity(Vector3 velocity)
+void RigidBody::SetLinearVelocity(const Vector3& velocity)
 {
     if (body_)
     {
@@ -297,7 +297,7 @@ void RigidBody::SetLinearVelocity(Vector3 velocity)
     }
 }
 
-void RigidBody::SetLinearFactor(Vector3 factor)
+void RigidBody::SetLinearFactor(const Vector3& factor)
 {
     if (body_)
     {
@@ -324,7 +324,7 @@ void RigidBody::SetLinearDamping(float damping)
     }
 }
 
-void RigidBody::SetAngularVelocity(Vector3 velocity)
+void RigidBody::SetAngularVelocity(const Vector3& velocity)
 {
     if (body_)
     {
@@ -335,7 +335,7 @@ void RigidBody::SetAngularVelocity(Vector3 velocity)
     }
 }
 
-void RigidBody::SetAngularFactor(Vector3 factor)
+void RigidBody::SetAngularFactor(const Vector3& factor)
 {
     if (body_)
     {
@@ -371,7 +371,7 @@ void RigidBody::SetFriction(float friction)
     }
 }
 
-void RigidBody::SetAnisotropicFriction(Vector3 friction)
+void RigidBody::SetAnisotropicFriction(const Vector3& friction)
 {
     if (body_)
     {
@@ -705,7 +705,7 @@ void RigidBody::ApplyWorldTransform(const Vector3& newWorldPosition, const Quate
     // where node is already null
     if (!node_ || !physicsWorld_)
         return;
-    
+
     physicsWorld_->SetApplyingTransforms(true);
 
     // Apply transform to the SmoothedTransform component instead of node transform if available

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

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

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

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

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

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

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

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

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

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

@@ -203,6 +203,44 @@ public:
     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 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))
@@ -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 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 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)
 
 }

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

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

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

@@ -81,11 +81,11 @@ void ScriptInstance::RegisterObject(Context* context)
     context->RegisterFactory<ScriptInstance>(LOGIC_CATEGORY);
 
     ACCESSOR_ATTRIBUTE(ScriptInstance, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(ScriptInstance, VAR_BUFFER, "Delayed Method Calls", GetDelayedCallsAttr, SetDelayedCallsAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_FILE | AM_NOEDIT);
-    ACCESSOR_ATTRIBUTE(ScriptInstance, VAR_RESOURCEREF, "Script File", GetScriptFileAttr, SetScriptFileAttr, ResourceRef, ResourceRef(ScriptFile::GetTypeStatic()), AM_DEFAULT);
+    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);
-    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)
@@ -353,13 +353,13 @@ void ScriptInstance::RemoveEventHandlersExcept(const PODVector<StringHash>& exce
     UnsubscribeFromAllEventsExcept(exceptions, true);
 }
 
-void ScriptInstance::SetScriptFileAttr(ResourceRef value)
+void ScriptInstance::SetScriptFileAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SetScriptFile(cache->GetResource<ScriptFile>(value.name_));
 }
 
-void ScriptInstance::SetDelayedCallsAttr(PODVector<unsigned char> value)
+void ScriptInstance::SetDelayedCallsAttr(const PODVector<unsigned char>& value)
 {
     MemoryBuffer buf(value);
     delayedCalls_.Resize(buf.ReadVLE());
@@ -376,7 +376,7 @@ void ScriptInstance::SetDelayedCallsAttr(PODVector<unsigned char> value)
         UpdateEventSubscription();
 }
 
-void ScriptInstance::SetScriptDataAttr(PODVector<unsigned char> data)
+void ScriptInstance::SetScriptDataAttr(const PODVector<unsigned char>& data)
 {
     if (scriptObject_ && methods_[METHOD_LOAD])
     {
@@ -387,7 +387,7 @@ void ScriptInstance::SetScriptDataAttr(PODVector<unsigned char> data)
     }
 }
 
-void ScriptInstance::SetScriptNetworkDataAttr(PODVector<unsigned char> data)
+void ScriptInstance::SetScriptNetworkDataAttr(const PODVector<unsigned char>& data)
 {
     if (scriptObject_ && methods_[METHOD_READNETWORKUPDATE])
     {

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

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

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

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

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

@@ -59,7 +59,7 @@ void BorderImage::RegisterObject(Context* context)
     context->RegisterFactory<BorderImage>(UI_CATEGORY);
 
     COPY_BASE_ATTRIBUTES(BorderImage, UIElement);
-    ACCESSOR_ATTRIBUTE(BorderImage, VAR_RESOURCEREF, "Texture", GetTextureAttr, SetTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_FILE);
+    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, "Border", GetBorder, SetBorder, 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;
 }
 
-void BorderImage::SetTextureAttr(ResourceRef value)
+void BorderImage::SetTextureAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SetTexture(cache->GetResource<Texture2D>(value.name_));

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

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

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

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

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

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

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

@@ -54,14 +54,14 @@ Sprite::~Sprite()
 void Sprite::RegisterObject(Context* context)
 {
     context->RegisterFactory<Sprite>(UI_CATEGORY);
-    
+
     REF_ACCESSOR_ATTRIBUTE(Sprite, VAR_STRING, "Name", GetName, SetName, String, String::EMPTY, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Sprite, VAR_VECTOR2, "Position", GetPosition, SetPosition, Vector2, Vector2::ZERO, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Sprite, VAR_INTVECTOR2, "Size", GetSize, SetSize, IntVector2, IntVector2::ZERO, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Sprite, VAR_INTVECTOR2, "Hotspot", GetHotSpot, SetHotSpot, IntVector2, IntVector2::ZERO, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Sprite, VAR_VECTOR2, "Scale", GetScale, SetScale, Vector2, Vector2::ONE, AM_FILE);
     ACCESSOR_ATTRIBUTE(Sprite, VAR_FLOAT, "Rotation", GetRotation, SetRotation, float, 0.0f, AM_FILE);
-    ACCESSOR_ATTRIBUTE(Sprite, VAR_RESOURCEREF, "Texture", GetTextureAttr, SetTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_FILE);
+    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);
     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);
@@ -97,15 +97,15 @@ void Sprite::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexDat
     if (GetDerivedOpacity() < 1.0f || color_[C_TOPLEFT].a_ < 1.0f || color_[C_TOPRIGHT].a_ < 1.0f ||
         color_[C_BOTTOMLEFT].a_ < 1.0f || color_[C_BOTTOMRIGHT].a_ < 1.0f)
         allOpaque = false;
-    
+
     const IntVector2& size = GetSize();
     UIBatch batch(this, blendMode_ == BLEND_REPLACE && !allOpaque ? BLEND_ALPHA : blendMode_, currentScissor, texture_, &vertexData);
-    
+
     batch.AddQuad(GetTransform(), 0, 0, size.x_, size.y_, imageRect_.left_, imageRect_.top_, imageRect_.right_ -
         imageRect_.left_, imageRect_.bottom_ - imageRect_.top_);
-    
+
     UIBatch::AddOrMerge(batch, batches);
-    
+
     // Reset hovering for next frame
     hovering_ = false;
 }
@@ -203,9 +203,9 @@ const Matrix3x4& Sprite::GetTransform() const
     if (positionDirty_)
     {
         Vector2 pos = floatPosition_;
-        
+
         Matrix3x4 parentTransform;
-        
+
         if (parent_)
         {
             Sprite* parentSprite = dynamic_cast<Sprite*>(parent_);
@@ -217,16 +217,16 @@ const Matrix3x4& Sprite::GetTransform() const
                 parentTransform = Matrix3x4::IDENTITY;
                 parentTransform.SetTranslation(Vector3((float)parentScreenPos.x_, (float)parentScreenPos.y_, 0.0f));
             }
-            
+
             switch (GetHorizontalAlignment())
             {
             case HA_LEFT:
                 break;
-                
+
             case HA_CENTER:
                 pos.x_ += (float)(parent_->GetSize().x_ / 2);
                 break;
-                
+
             case HA_RIGHT:
                 pos.x_ += (float)parent_->GetSize().x_;
                 break;
@@ -235,11 +235,11 @@ const Matrix3x4& Sprite::GetTransform() const
             {
             case VA_TOP:
                 break;
-                
+
             case VA_CENTER:
                 pos.y_ += (float)(parent_->GetSize().y_ / 2);
                 break;
-                
+
             case VA_BOTTOM:
                 pos.y_ += (float)(parent_->GetSize().y_);
                 break;
@@ -247,24 +247,24 @@ const Matrix3x4& Sprite::GetTransform() const
         }
         else
             parentTransform = Matrix3x4::IDENTITY;
-        
+
         Matrix3x4 hotspotAdjust(Matrix3x4::IDENTITY);
         hotspotAdjust.SetTranslation(Vector3((float)-hotSpot_.x_, (float)-hotSpot_.y_, 0.0f));
-        
+
         Matrix3x4 mainTransform(Vector3(pos, 0.0f), Quaternion(rotation_, Vector3::FORWARD), Vector3(scale_, 1.0f));
-        
+
         transform_ = parentTransform * mainTransform * hotspotAdjust;
         positionDirty_ = false;
-        
+
         // Calculate an approximate screen position for GetElementAt(), or pixel-perfect child elements
         Vector3 topLeftCorner = transform_ * Vector3::ZERO;
         screenPosition_ = IntVector2((int)topLeftCorner.x_, (int)topLeftCorner.y_);
     }
-    
+
     return transform_;
 }
 
-void Sprite::SetTextureAttr(ResourceRef value)
+void Sprite::SetTextureAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SetTexture(cache->GetResource<Texture2D>(value.name_));

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

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

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

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

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

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

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

@@ -66,10 +66,10 @@ Text3D::~Text3D()
 void Text3D::RegisterObject(Context* context)
 {
     context->RegisterFactory<Text3D>(GEOMETRY_CATEGORY);
-    
+
     ACCESSOR_ATTRIBUTE(Text3D, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Text3D, VAR_RESOURCEREF, "Font", GetFontAttr, SetFontAttr, ResourceRef, ResourceRef(Font::GetTypeStatic()), AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Text3D, VAR_RESOURCEREF, "Material", GetMaterialAttr, SetMaterialAttr, ResourceRef, ResourceRef(Material::GetTypeStatic()), AM_DEFAULT);
+    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_STRING, "Text", text_.text_, String::EMPTY, 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)
 {
     distance_ = frame.camera_->GetDistance(GetWorldBoundingBox().Center());
-    
+
     if (faceCameraMode_ != FC_NONE)
     {
         Vector3 worldPosition = node_->GetWorldPosition();
@@ -111,7 +111,7 @@ void Text3D::UpdateBatches(const FrameInfo& frame)
             worldPosition, node_->GetWorldRotation(), faceCameraMode_), node_->GetWorldScale());
         worldBoundingBoxDirty_ = true;
     }
-    
+
     for (unsigned i = 0; i < batches_.Size(); ++i)
     {
         batches_[i].distance_ = distance_;
@@ -130,7 +130,7 @@ void Text3D::UpdateGeometry(const FrameInfo& frame)
                 uiBatches_[i].vertexStart_) / UI_VERTEX_SIZE);
         }
     }
-    
+
     if ((geometryDirty_ || vertexBuffer_->IsDataLost()) && uiVertexData_.Size())
     {
         unsigned vertexCount = uiVertexData_.Size() / UI_VERTEX_SIZE;
@@ -138,7 +138,7 @@ void Text3D::UpdateGeometry(const FrameInfo& frame)
             vertexBuffer_->SetSize(vertexCount, MASK_POSITION | MASK_COLOR | MASK_TEXCOORD1);
         vertexBuffer_->SetData(&uiVertexData_[0]);
     }
-    
+
     geometryDirty_ = false;
 }
 
@@ -153,7 +153,7 @@ UpdateGeometryType Text3D::GetUpdateGeometryType()
 void Text3D::SetMaterial(Material* material)
 {
     material_ = material;
-    
+
     UpdateTextMaterials(true);
 }
 
@@ -166,7 +166,7 @@ bool Text3D::SetFont(const String& fontName, int size)
     MarkTextDirty();
     UpdateTextBatches();
     UpdateTextMaterials();
-    
+
     return success;
 }
 
@@ -177,14 +177,14 @@ bool Text3D::SetFont(Font* font, int size)
     MarkTextDirty();
     UpdateTextBatches();
     UpdateTextMaterials();
-    
+
     return success;
 }
 
 void Text3D::SetText(const String& text)
 {
     text_.SetText(text);
-    
+
     // Changing text requires materials to be re-evaluated, in case the font is multi-page
     MarkTextDirty();
     UpdateTextBatches();
@@ -194,49 +194,49 @@ void Text3D::SetText(const String& text)
 void Text3D::SetAlignment(HorizontalAlignment hAlign, VerticalAlignment vAlign)
 {
     text_.SetAlignment(hAlign, vAlign);
-    
+
     MarkTextDirty();
 }
 
 void Text3D::SetHorizontalAlignment(HorizontalAlignment align)
 {
     text_.SetHorizontalAlignment(align);
-    
+
     MarkTextDirty();
 }
 
 void Text3D::SetVerticalAlignment(VerticalAlignment align)
 {
     text_.SetVerticalAlignment(align);
-    
+
     MarkTextDirty();
 }
 
 void Text3D::SetTextAlignment(HorizontalAlignment align)
 {
     text_.SetTextAlignment(align);
-    
+
     MarkTextDirty();
 }
 
 void Text3D::SetRowSpacing(float spacing)
 {
     text_.SetRowSpacing(spacing);
-    
+
     MarkTextDirty();
 }
 
 void Text3D::SetWordwrap(bool enable)
 {
     text_.SetWordwrap(enable);
-    
+
     MarkTextDirty();
 }
 
 void Text3D::SetTextEffect(TextEffect textEffect)
 {
     text_.SetTextEffect(textEffect);
-    
+
     MarkTextDirty();
     UpdateTextMaterials(true);
 }
@@ -244,7 +244,7 @@ void Text3D::SetTextEffect(TextEffect textEffect)
 void Text3D::SetEffectColor(const Color& effectColor)
 {
     text_.SetEffectColor(effectColor);
-    
+
     MarkTextDirty();
     UpdateTextMaterials();
 }
@@ -252,7 +252,7 @@ void Text3D::SetEffectColor(const Color& effectColor)
 void Text3D::SetEffectDepthBias(float bias)
 {
     text_.SetEffectDepthBias(bias);
-    
+
     MarkTextDirty();
 }
 
@@ -260,28 +260,28 @@ void Text3D::SetWidth(int width)
 {
     text_.SetMinWidth(width);
     text_.SetWidth(width);
-    
+
     MarkTextDirty();
 }
 
 void Text3D::SetColor(const Color& color)
 {
     text_.SetColor(color);
-    
+
     MarkTextDirty();
 }
 
 void Text3D::SetColor(Corner corner, const Color& color)
 {
     text_.SetColor(corner, color);
-    
+
     MarkTextDirty();
 }
 
 void Text3D::SetOpacity(float opacity)
 {
     text_.SetOpacity(opacity);
-    
+
     MarkTextDirty();
 }
 
@@ -290,7 +290,7 @@ void Text3D::SetFaceCameraMode(FaceCameraMode mode)
     if (mode != faceCameraMode_)
     {
         faceCameraMode_ = mode;
-        
+
         // Bounding box must be recalculated
         OnMarkedDirty(node_);
     }
@@ -404,7 +404,7 @@ float Text3D::GetOpacity() const
 void Text3D::OnNodeSet(Node* node)
 {
     Drawable::OnNodeSet(node);
-    
+
     if (node)
         customWorldTransform_ = node->GetWorldTransform();
 }
@@ -413,7 +413,7 @@ void Text3D::OnWorldBoundingBoxUpdate()
 {
     if (textDirty_)
         UpdateTextBatches();
-    
+
     // In face camera mode, use the last camera rotation to build the world bounding box
     worldBoundingBox_ = boundingBox_.Transformed(faceCameraMode_ != FC_NONE ? Matrix3x4(node_->GetWorldPosition(),
         customWorldTransform_.Rotation(), node_->GetWorldScale()) : node_->GetWorldTransform());
@@ -422,18 +422,18 @@ void Text3D::OnWorldBoundingBoxUpdate()
 void Text3D::MarkTextDirty()
 {
     textDirty_ = true;
-    
+
     OnMarkedDirty(node_);
     MarkNetworkUpdate();
 }
 
-void Text3D::SetMaterialAttr(ResourceRef value)
+void Text3D::SetMaterialAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SetMaterial(cache->GetResource<Material>(value.name_));
 }
 
-void Text3D::SetFontAttr(ResourceRef value)
+void Text3D::SetFontAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     text_.font_ = cache->GetResource<Font>(value.name_);
@@ -453,42 +453,42 @@ void Text3D::UpdateTextBatches()
 {
     uiBatches_.Clear();
     uiVertexData_.Clear();
-    
+
     text_.GetBatches(uiBatches_, uiVertexData_, IntRect::ZERO);
-    
+
     Vector3 offset(Vector3::ZERO);
-    
+
     switch (text_.GetHorizontalAlignment())
     {
     case HA_LEFT:
         break;
-        
+
     case HA_CENTER:
         offset.x_ -= (float)text_.GetWidth() * 0.5f;
         break;
-        
+
     case HA_RIGHT:
         offset.x_ -= (float)text_.GetWidth();
         break;
     }
-    
+
     switch (text_.GetVerticalAlignment())
     {
     case VA_TOP:
         break;
-        
+
     case VA_CENTER:
         offset.y_ -= (float)text_.GetHeight() * 0.5f;
         break;
-        
+
     case VA_BOTTOM:
         offset.y_ -= (float)text_.GetHeight();
         break;
     }
-    
+
     boundingBox_.defined_ = false;
     boundingBox_.min_ = boundingBox_.max_ = Vector3::ZERO;
-    
+
     for (unsigned i = 0; i < uiVertexData_.Size(); i += UI_VERTEX_SIZE)
     {
         Vector3& position = *(reinterpret_cast<Vector3*>(&uiVertexData_[i]));
@@ -497,7 +497,7 @@ void Text3D::UpdateTextBatches()
         position.y_ = -position.y_;
         boundingBox_.Merge(position);
     }
-    
+
     textDirty_ = false;
     geometryDirty_ = true;
 }
@@ -506,7 +506,7 @@ void Text3D::UpdateTextMaterials(bool forceUpdate)
 {
     batches_.Resize(uiBatches_.Size());
     geometries_.Resize(uiBatches_.Size());
-    
+
     for (unsigned i = 0; i < batches_.Size(); ++i)
     {
         if (!geometries_[i])
@@ -515,7 +515,7 @@ void Text3D::UpdateTextMaterials(bool forceUpdate)
             geometry->SetVertexBuffer(0, vertexBuffer_, MASK_POSITION | MASK_COLOR | MASK_TEXCOORD1);
             batches_[i].geometry_ = geometries_[i] = geometry;
         }
-        
+
         if (!batches_[i].material_ || forceUpdate)
         {
             // If material not defined, create a reasonable default from scratch
@@ -554,7 +554,7 @@ void Text3D::UpdateTextMaterials(bool forceUpdate)
             else
                 batches_[i].material_ = material_->Clone();
         }
-        
+
         Material* material = batches_[i].material_;
         Texture* texture = uiBatches_[i].texture_;
         material->SetTexture(TU_DIFFUSE, texture);

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

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

+ 2 - 2
Source/Engine/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);
     REF_ACCESSOR_ATTRIBUTE(AnimatedSprite2D, VAR_COLOR, "Color", GetColor, SetColor, Color, Color::WHITE, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(AnimatedSprite2D, VAR_FLOAT, "Speed", GetSpeed, SetSpeed, float, 1.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(AnimatedSprite2D, VAR_RESOURCEREF, "Animation Set", GetAnimationSetAttr, SetAnimationSetAttr, ResourceRef, ResourceRef(AnimatedSprite2D::GetTypeStatic()), AM_DEFAULT);
+    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);
     ENUM_ACCESSOR_ATTRIBUTE(AnimatedSprite2D, "Loop Mode", GetLoopMode, SetLoopMode, LoopMode2D, loopModeNames, LM_DEFAULT, AM_DEFAULT);
     COPY_BASE_ATTRIBUTES(AnimatedSprite2D, Drawable);
@@ -244,7 +244,7 @@ Node* AnimatedSprite2D::GetRootNode() const
     return rootNode_;
 }
 
-void AnimatedSprite2D::SetAnimationSetAttr(ResourceRef value)
+void AnimatedSprite2D::SetAnimationSetAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SetAnimationSet(cache->GetResource<AnimationSet2D>(value.name_));

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

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

+ 4 - 4
Source/Engine/Urho2D/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, "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);
-    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);
 }
 
@@ -173,7 +173,7 @@ const Vector<Vertex2D>& Drawable2D::GetVertices()
     return vertices_;
 }
 
-void Drawable2D::SetSpriteAttr(ResourceRef value)
+void Drawable2D::SetSpriteAttr(const ResourceRef& value)
 {
     // Delay applying material update
     materialUpdatePending_ = true;
@@ -225,7 +225,7 @@ void Drawable2D::SetBlendModeAttr(BlendMode mode)
     SetBlendMode(mode);
 }
 
-void Drawable2D::SetMaterialAttr(ResourceRef value)
+void Drawable2D::SetMaterialAttr(const ResourceRef& value)
 {
     // Delay applying material update
     materialUpdatePending_ = true;

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

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

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

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

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

@@ -34,7 +34,7 @@ class ParticleEffect2D;
 {
     /// Time to live.
     float timeToLive_;
-    
+
     /// Position.
     Vector2 position_;
     /// Size.
@@ -99,7 +99,7 @@ public:
     unsigned GetMaxParticles() const { return particles_.Size(); }
 
     /// Set particle model attr.
-    void SetParticleEffectAttr(ResourceRef value);
+    void SetParticleEffectAttr(const ResourceRef& value);
     /// Return particle model attr.
     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);
     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_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_FLOAT, "Linear Damping", GetLinearDamping, SetLinearDamping, 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_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_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);
 
     COPY_BASE_ATTRIBUTES(RigidBody2D, Component);
@@ -148,7 +148,7 @@ void RigidBody2D::SetInertia(float inertia)
     MarkNetworkUpdate();
 }
 
-void RigidBody2D::SetMassCenter(Vector2 center)
+void RigidBody2D::SetMassCenter(const Vector2& center)
 {
     b2Vec2 b2Center = ToB2Vec2(center);
     if (massData_.center == b2Center)
@@ -271,7 +271,7 @@ void RigidBody2D::SetAwake(bool awake)
     MarkNetworkUpdate();
 }
 
-void RigidBody2D::SetLinearVelocity(Vector2 linearVelocity)
+void RigidBody2D::SetLinearVelocity(const Vector2& linearVelocity)
 {
     b2Vec2 b2linearVelocity = ToB2Vec2(linearVelocity);
     if (bodyDef_.linearVelocity == b2linearVelocity)
@@ -486,7 +486,7 @@ void RigidBody2D::OnNodeSet(Node* node)
         node->AddListener(this);
         Scene* scene = GetScene();
         physicsWorld_ = scene->GetOrCreateComponent<PhysicsWorld2D>();
-        
+
         CreateBody();
         physicsWorld_->AddRigidBody(this);
     }

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

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

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

@@ -50,7 +50,7 @@ TileMap2D::~TileMap2D()
 void TileMap2D::RegisterObject(Context* context)
 {
     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)
@@ -159,7 +159,7 @@ bool TileMap2D::PositionToTileIndex(int& x, int& y, const Vector2& position) con
     return info_.PositionToTileIndex(x, y, position);
 }
 
-void TileMap2D::SetTmxFileAttr(ResourceRef value)
+void TileMap2D::SetTmxFileAttr(const ResourceRef& value)
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     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;
 
     /// Set tile map file attribute.
-    void SetTmxFileAttr(ResourceRef value);
+    void SetTmxFileAttr(const ResourceRef& value);
     /// Return tile map file attribute.
     ResourceRef GetTmxFileAttr() const;
 

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