瀏覽代碼

Added scene timescale attribute.

Lasse Öörni 13 年之前
父節點
當前提交
7813601540

+ 1 - 0
Docs/ScriptAPI.dox

@@ -1430,6 +1430,7 @@ Properties:<br>
 - Node@ parent
 - VariantMap vars (readonly)
 - bool active
+- float timeScale
 - float smoothingConstant
 - float snapThreshold
 - bool asyncLoading (readonly)

+ 2 - 0
Engine/Engine/SceneAPI.cpp

@@ -182,6 +182,8 @@ static void RegisterScene(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Scene", "void Update(float)", asMETHOD(Scene, Update), asCALL_THISCALL);
     engine->RegisterObjectMethod("Scene", "void set_active(bool)", asMETHOD(Scene, SetActive), asCALL_THISCALL);
     engine->RegisterObjectMethod("Scene", "bool get_active() const", asMETHOD(Scene, IsActive), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Scene", "void set_timeScale(float)", asMETHOD(Scene, SetTimeScale), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Scene", "float get_timeScale() const", asMETHOD(Scene, GetTimeScale), asCALL_THISCALL);
     engine->RegisterObjectMethod("Scene", "void set_smoothingConstant(float)", asMETHOD(Scene, SetSmoothingConstant), asCALL_THISCALL);
     engine->RegisterObjectMethod("Scene", "float get_smoothingConstant() const", asMETHOD(Scene, GetSmoothingConstant), asCALL_THISCALL);
     engine->RegisterObjectMethod("Scene", "void set_snapThreshold(float)", asMETHOD(Scene, SetSnapThreshold), asCALL_THISCALL);

+ 16 - 12
Engine/Graphics/ParticleEmitter.cpp

@@ -69,6 +69,7 @@ ParticleEmitter::ParticleEmitter(Context* context) :
     sizeMul_(1.0f),
     active_(true),
     updateInvisible_(false),
+    lastTimeStep_(0.0f),
     lastUpdateFrameNumber_(M_MAX_UNSIGNED)
 {
     SetParticleColor(Color(1.0f, 1.0f, 1.0f));
@@ -99,8 +100,6 @@ void ParticleEmitter::RegisterObject(Context* context)
 
 void ParticleEmitter::Update(const FrameInfo& frame)
 {
-    float timeStep = frame.timeStep_;
-    
     // If there is an amount mismatch between particles and billboards, correct it
     if (particles_.Size() != billboards_.Size())
         SetNumBillboards(particles_.Size());
@@ -108,7 +107,7 @@ void ParticleEmitter::Update(const FrameInfo& frame)
     bool needBillboardUpdate = false;
     
     // Check active/inactive period switching
-    periodTimer_ += timeStep;
+    periodTimer_ += lastTimeStep_;
     if (active_)
     {
         if (activeTime_ && periodTimer_ >= activeTime_)
@@ -129,7 +128,7 @@ void ParticleEmitter::Update(const FrameInfo& frame)
     // Check for emitting a new particle
     if (active_)
     {
-        emissionTimer_ += timeStep;
+        emissionTimer_ += lastTimeStep_;
         if (emissionTimer_ > 0.0f)
         {
             emissionTimer_ -= Lerp(intervalMin_, intervalMax_, Random(1.0f));
@@ -160,32 +159,32 @@ void ParticleEmitter::Update(const FrameInfo& frame)
                 billboard.enabled_ = false;
                 continue;
             }
-            particle.timer_ += timeStep;
+            particle.timer_ += lastTimeStep_;
             
             // Velocity & position
             if (constanceForce_ != Vector3::ZERO)
             {
                 if (relative_)
-                    particle.velocity_ += timeStep * relativeConstantForce;
+                    particle.velocity_ += lastTimeStep_ * relativeConstantForce;
                 else
-                    particle.velocity_ += timeStep * constanceForce_;
+                    particle.velocity_ += lastTimeStep_ * constanceForce_;
             }
             if (dampingForce_ != 0.0f)
             {
                 Vector3 force = -dampingForce_ * particle.velocity_;
-                particle.velocity_ += timeStep * force;
+                particle.velocity_ += lastTimeStep_ * force;
             }
-            billboard.position_ += timeStep * particle.velocity_ * scaleVector;
+            billboard.position_ += lastTimeStep_ * particle.velocity_ * scaleVector;
             
             // Rotation
-            billboard.rotation_ += timeStep * particle.rotationSpeed_;
+            billboard.rotation_ += lastTimeStep_ * particle.rotationSpeed_;
             
             // Scaling
             if (sizeAdd_ != 0.0f || sizeMul_ != 1.0f)
             {
-                particle.scale_ += timeStep * sizeAdd_;
+                particle.scale_ += lastTimeStep_ * sizeAdd_;
                 if (sizeMul_ != 1.0f)
-                    particle.scale_ *= (timeStep * (sizeMul_ - 1.0f)) + 1.0f;
+                    particle.scale_ *= (lastTimeStep_ * (sizeMul_ - 1.0f)) + 1.0f;
                 billboard.size_ = particle.size_ * particle.scale_;
             }
             
@@ -575,6 +574,11 @@ void ParticleEmitter::GetVector3MinMax(const XMLElement& element, Vector3& minVa
 
 void ParticleEmitter::HandleScenePostUpdate(StringHash eventType, VariantMap& eventData)
 {
+    // Store scene's timestep and use it instead of global timestep, as time scale may be other than 1
+    using namespace ScenePostUpdate;
+    
+    lastTimeStep_ = eventData[P_TIMESTEP].GetFloat();
+    
     // If no invisible update, check that the billboardset is in view (framenumber has changed)
     if (updateInvisible_ || viewFrameNumber_ != lastUpdateFrameNumber_)
     {

+ 3 - 1
Engine/Graphics/ParticleEmitter.h

@@ -194,7 +194,9 @@ private:
     bool active_;
     /// Update when invisible flag.
     bool updateInvisible_;
-    /// Rendering renderer framenumber on which was last updated.
+    /// Last scene timestep.
+    float lastTimeStep_;
+    /// Rendering framenumber on which was last updated.
     unsigned lastUpdateFrameNumber_;
 };
 

+ 10 - 0
Engine/Scene/Scene.cpp

@@ -55,6 +55,7 @@ Scene::Scene(Context* context) :
     localNodeID_(FIRST_LOCAL_ID),
     localComponentID_(FIRST_LOCAL_ID),
     checksum_(0),
+    timeScale_(1.0f),
     smoothingConstant_(DEFAULT_SMOOTHING_CONSTANT),
     snapThreshold_(DEFAULT_SNAP_THRESHOLD),
     active_(true),
@@ -96,6 +97,7 @@ void Scene::RegisterObject(Context* context)
     REF_ACCESSOR_ATTRIBUTE(Scene, VAR_VECTOR3, "Position", GetPosition, SetPosition, Vector3, Vector3::ZERO, AM_DEFAULT | AM_LATESTDATA);
     REF_ACCESSOR_ATTRIBUTE(Scene, VAR_QUATERNION, "Rotation", GetRotation, SetRotation, Quaternion, Quaternion::IDENTITY, AM_FILE);
     REF_ACCESSOR_ATTRIBUTE(Scene, VAR_VECTOR3, "Scale", GetScale, SetScale, Vector3, Vector3::ONE, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE(Scene, VAR_FLOAT, "Time Scale", GetTimeScale, SetTimeScale, float, 1.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Scene, VAR_FLOAT, "Smoothing Constant", GetSmoothingConstant, SetSmoothingConstant, float, DEFAULT_SMOOTHING_CONSTANT, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Scene, VAR_FLOAT, "Snap Threshold", GetSnapThreshold, SetSnapThreshold, float, DEFAULT_SNAP_THRESHOLD, AM_DEFAULT);
     ATTRIBUTE(Scene, VAR_INT, "Next Replicated Node ID", replicatedNodeID_, FIRST_REPLICATED_ID, AM_FILE | AM_NOEDIT);
@@ -381,6 +383,12 @@ void Scene::SetActive(bool enable)
     active_ = enable;
 }
 
+void Scene::SetTimeScale(float scale)
+{
+    timeScale_ = Max(scale, M_EPSILON);
+    Node::MarkNetworkUpdate();
+}
+
 void Scene::SetSmoothingConstant(float constant)
 {
     smoothingConstant_ = Max(constant, M_EPSILON);
@@ -486,6 +494,8 @@ void Scene::Update(float timeStep)
     
     PROFILE(UpdateScene);
     
+    timeStep *= timeScale_;
+    
     using namespace SceneUpdate;
     
     VariantMap eventData;

+ 6 - 0
Engine/Scene/Scene.h

@@ -100,6 +100,8 @@ public:
     void Clear();
     /// Set active flag. Only active scenes will be updated automatically.
     void SetActive(bool enable);
+    /// Set update time scale. 1.0 = real time (default.)
+    void SetTimeScale(float scale);
     /// Set network client motion smoothing constant.
     void SetSmoothingConstant(float constant);
     /// Set network client motion smoothing snap threshold.
@@ -129,6 +131,8 @@ public:
     const String& GetFileName() const { return fileName_; }
     /// Return source file checksum.
     unsigned GetChecksum() const { return checksum_; }
+    /// Return update time scale.
+    float GetTimeScale() const { return timeScale_; }
     /// Return motion smoothing constant.
     float GetSmoothingConstant() const { return smoothingConstant_; }
     /// Return motion smoothing snap threshold.
@@ -221,6 +225,8 @@ private:
     unsigned localComponentID_;
     /// Scene source file checksum.
     unsigned checksum_;
+    /// Scene update time scale.
+    float timeScale_;
     /// Motion smoothing constant.
     float smoothingConstant_;
     /// Motion smoothing snap threshold.