Просмотр исходного кода

Added reflection related functions to Plane. Fixed rendering a SkyBox from multiple views during the same frame. Better error message in ShaderCompiler if input file can not be opened.

Lasse Öörni 12 лет назад
Родитель
Сommit
a7d8f0fd18

+ 1 - 1
Source/Engine/Graphics/Batch.h

@@ -102,7 +102,7 @@ struct Batch
     ShaderVariation* pixelShader_;
     /// %Geometry type.
     GeometryType geometryType_;
-    /// Override view transform flag.
+    /// Override view transform flag. When set, the camera's view transform is replaced with an identity matrix.
     bool overrideView_;
     /// Base batch flag. This tells to draw the object fully without light optimizations.
     bool isBase_;

+ 10 - 3
Source/Engine/Graphics/Skybox.cpp

@@ -36,7 +36,7 @@ extern const char* GEOMETRY_CATEGORY;
 
 Skybox::Skybox(Context* context) :
     StaticModel(context),
-    customWorldTransform_(Matrix3x4::IDENTITY)
+    lastFrame_(0)
 {
 }
 
@@ -60,13 +60,20 @@ void Skybox::UpdateBatches(const FrameInfo& frame)
 {
     distance_ = 0.0f;
 
+    if (frame.frameNumber_ != lastFrame_)
+    {
+        customWorldTransforms_.Clear();
+        lastFrame_ = frame.frameNumber_;
+    }
+
     // Follow only the camera rotation, not position
     Matrix3x4 customView(Vector3::ZERO, frame.camera_->GetNode()->GetWorldRotation().Inverse(), Vector3::ONE);
-    customWorldTransform_ = customView * node_->GetWorldTransform();
+    HashMap<Camera*, Matrix3x4>::Iterator it = customWorldTransforms_.Insert(MakePair(frame.camera_, customView *
+        node_->GetWorldTransform()));
 
     for (unsigned i = 0; i < batches_.Size(); ++i)
     {
-        batches_[i].worldTransform_ = &customWorldTransform_;
+        batches_[i].worldTransform_ = &it->second_;
         batches_[i].distance_ = 0.0f;
         batches_[i].overrideView_ = true;
     }

+ 4 - 2
Source/Engine/Graphics/Skybox.h

@@ -49,8 +49,10 @@ protected:
     /// Recalculate the world-space bounding box.
     virtual void OnWorldBoundingBoxUpdate();
     
-    /// Custom world transform.
-    Matrix3x4 customWorldTransform_;
+    /// Custom world transform per camera.
+    HashMap<Camera*, Matrix3x4> customWorldTransforms_;
+    /// Last frame counter for knowing when to erase the custom world transforms of previous frame.
+    unsigned lastFrame_;
 };
 
 }

+ 3 - 1
Source/Engine/LuaScript/pkgs/Math/Plane.pkg

@@ -13,7 +13,9 @@ class Plane
     void Define(const Vector3& normal, const Vector3& point);
     
     float Distance(const Vector3& point) const;
-    
+    Vector3 Reflect(const Vector3& direction) const;
+    Matrix3x4 ReflectionMatrix() const;
+
     Vector3 normal_ @ normal;
     Vector3 absNormal_ @ absNormal;
     float intercept_ @ intercept;

+ 25 - 2
Source/Engine/Math/Plane.h

@@ -22,7 +22,7 @@
 
 #pragma once
 
-#include "Vector3.h"
+#include "Matrix3x4.h"
 
 namespace Urho3D
 {
@@ -75,7 +75,30 @@ public:
     
     /// Return signed distance to a point.
     float Distance(const Vector3& point) const { return normal_.DotProduct(point) - intercept_; }
-    
+    /// Reflect a normalized direction vector.
+    Vector3 Reflect(const Vector3& direction) const { return direction - (2.0f * normal_.DotProduct(direction) * normal_); }
+
+    /// Return a reflection matrix.
+    Matrix3x4 ReflectionMatrix() const
+    {
+        float negIntercept = -intercept_;
+
+        return Matrix3x4(
+            -2.0f * normal_.x_ * normal_.x_ + 1.0f,
+            -2.0f * normal_.x_ * normal_.y_,
+            -2.0f * normal_.x_ * normal_.z_,
+            -2.0f * normal_.x_ * negIntercept,
+            -2.0f * normal_.y_ * normal_.x_ ,
+            -2.0f * normal_.y_ * normal_.y_ + 1.0f,
+            -2.0f * normal_.y_ * normal_.z_,
+            -2.0f * normal_.y_ * negIntercept,
+            -2.0f * normal_.z_ * normal_.x_,
+            -2.0f * normal_.z_ * normal_.y_,
+            -2.0f * normal_.z_ * normal_.z_ + 1.0f,
+            -2.0f * normal_.z_ * negIntercept
+        );
+    }
+
     /// Plane normal.
     Vector3 normal_;
     /// Plane absolute normal.

+ 2 - 2
Source/Engine/Math/Quaternion.h

@@ -79,7 +79,7 @@ public:
         FromEulerAngles(x, y, z);
     }
     
-    /// Construct from the rotation difference between two vectors.
+    /// Construct from the rotation difference between two direction vectors.
     Quaternion(const Vector3& start, const Vector3& end)
     {
         FromRotationTo(start, end);
@@ -165,7 +165,7 @@ public:
     void FromAngleAxis(float angle, const Vector3& axis);
     /// Define from Euler angles (in degrees.)
     void FromEulerAngles(float x, float y, float z);
-    /// Define from the rotation difference between two vectors.
+    /// Define from the rotation difference between two direction vectors.
     void FromRotationTo(const Vector3& start, const Vector3& end);
     /// Define from orthonormal axes.
     void FromAxes(const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis);

+ 2 - 0
Source/Engine/Script/MathAPI.cpp

@@ -671,6 +671,8 @@ static void RegisterPlane(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Plane", "void Define(const Vector3&in, const Vector3&in, const Vector3&in)", asMETHODPR(Plane, Define, (const Vector3&, const Vector3&, const Vector3&), void), asCALL_THISCALL);
     engine->RegisterObjectMethod("Plane", "void Define(const Vector3&in, const Vector3&in)", asMETHODPR(Plane, Define, (const Vector3&, const Vector3&), void), asCALL_THISCALL);
     engine->RegisterObjectMethod("Plane", "float Distance(const Vector3&in) const", asMETHOD(Plane, Distance), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Plane", "Vector3 Reflect(const Vector3&in) const", asMETHOD(Plane, Reflect), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Plane", "Matrix3x4 get_reflectionMatrix() const", asMETHOD(Plane, ReflectionMatrix), asCALL_THISCALL);
     engine->RegisterObjectProperty("Plane", "Vector3 normal", offsetof(Plane, normal_));
     engine->RegisterObjectProperty("Plane", "Vector3 absNormal", offsetof(Plane, absNormal_));
     engine->RegisterObjectProperty("Plane", "float intercept", offsetof(Plane, intercept_));

+ 3 - 2
Source/Tools/ShaderCompiler/ShaderCompiler.cpp

@@ -279,9 +279,10 @@ void CompileShader(const String& fileName)
     
     XMLFile doc(context_);
     File source(context_);
-    source.Open(fileName);
-    if (!doc.Load(source))
+    if (!source.Open(fileName))
         ErrorExit("Could not open input file " + fileName);
+    if (!doc.Load(source))
+        ErrorExit("Could not parse input file " + fileName);
     
     XMLElement shaders = doc.GetRoot("shaders");
     if (!shaders)