Răsfoiți Sursa

Camera as component

Marko Pintera 13 ani în urmă
părinte
comite
89fa56ba91

+ 2 - 1
CamelotRenderer/Include/CmApplication.h

@@ -26,10 +26,11 @@ namespace CamelotEngine
 
 		private:
 			RenderWindow* mRenderWindow;
-			Camera* mCamera;
+			std::shared_ptr<Camera> mCamera;
 			HighLevelGpuProgramPtr mFragProg;
 			HighLevelGpuProgramPtr mVertProg;
 			TexturePtr mDbgTexture;
+			GameObjectPtr mCameraGO;
 	};
 
 	CM_EXPORT Application& gApplication();

+ 11 - 214
CamelotRenderer/Include/CmCamera.h

@@ -43,7 +43,7 @@ THE SOFTWARE.
 #include "CmQuaternion.h"
 #include "CmCommon.h"
 #include "CmRay.h"
-
+#include "CmComponent.h"
 
 namespace CamelotEngine {
 
@@ -102,7 +102,7 @@ namespace CamelotEngine {
             This is useful for implementing more complex Camera / object
             relationships i.e. having a camera attached to a world object.
     */
-    class CM_EXPORT Camera
+    class CM_EXPORT Camera : public Component
     {
 	protected:
         /// Orthographic or perspective?
@@ -140,8 +140,6 @@ namespace CamelotEngine {
         mutable Matrix4 mViewMatrix;
         /// Something's changed in the frustum shape?
         mutable bool mRecalcFrustum;
-        /// Something re the view pos has changed
-        mutable bool mRecalcView;
         /// Something re the frustum planes has changed
         mutable bool mRecalcFrustumPlanes;
         /// Something re the world space corners has changed
@@ -161,12 +159,8 @@ namespace CamelotEngine {
         virtual void calcProjectionParameters(float& left, float& right, float& bottom, float& top) const;
 		/// Update frustum if out of date
         virtual void updateFrustum(void) const;
-		/// Update view if out of date
-        virtual void updateView(void) const;
 		/// Implementation of updateFrustum (called if out of date)
 		virtual void updateFrustumImpl(void) const;
-		/// Implementation of updateView (called if out of date)
-		virtual void updateViewImpl(void) const;
         virtual void updateFrustumPlanes(void) const;
 		/// Implementation of updateFrustumPlanes (called if out of date)
 		virtual void updateFrustumPlanesImpl(void) const;
@@ -174,12 +168,10 @@ namespace CamelotEngine {
 		/// Implementation of updateWorldSpaceCorners (called if out of date)
 		virtual void updateWorldSpaceCornersImpl(void) const;
         virtual void updateVertexData(void) const;
-        virtual bool isViewOutOfDate(void) const;
+		virtual void updateView(void) const;
         virtual bool isFrustumOutOfDate(void) const;
         /// Signal to update frustum information.
         virtual void invalidateFrustum(void) const;
-        /// Signal to update view information.
-        virtual void invalidateView(void) const;
 
         mutable AxisAlignedBox mBoundingBox;
         mutable VertexData mVertexData;
@@ -352,12 +344,6 @@ namespace CamelotEngine {
         */
         virtual const Matrix4& getViewMatrix(void) const;
 
-		/** Calculate a view matrix for this frustum, relative to a potentially dynamic point. 
-			Mainly for use by OGRE internally when using camera-relative rendering
-			for frustums that are not the centre (e.g. texture projection)
-		*/
-		virtual void calcViewMatrixRelative(const Vector3& relPos, Matrix4& matToUpdate) const;
-
 		/** Set whether to use a custom view matrix on this frustum.
 		@remarks
 			This is an advanced method which allows you to manually set
@@ -519,31 +505,7 @@ namespace CamelotEngine {
 
         /// Small constant used to reduce far plane projection to avoid inaccuracies
         static const float INFINITE_FAR_PLANE_ADJUST;
-
-		/** Get the derived position of this frustum. */
-		virtual const Vector3& getPositionForViewUpdate(void) const;
-		/** Get the derived orientation of this frustum. */
-		virtual const Quaternion& getOrientationForViewUpdate(void) const;
     protected:
-        /// Camera orientation, quaternion style
-        Quaternion mOrientation;
-
-        /// Camera position - default (0,0,0)
-        Vector3 mPosition;
-
-        /// Derived orientation/position of the camera, including reflection
-        mutable Quaternion mDerivedOrientation;
-        mutable Vector3 mDerivedPosition;
-
-        /// float world orientation/position of the camera
-        mutable Quaternion mRealOrientation;
-        mutable Vector3 mRealPosition;
-
-        /// Whether to yaw around a fixed axis.
-        bool mYawFixed;
-        /// Fixed axis to yaw around
-        Vector3 mYawFixedAxis;
-
         /// Rendering type
         PolygonMode mSceneDetail;
 
@@ -558,8 +520,6 @@ namespace CamelotEngine {
         mutable vector<Plane>::type mWindowClipPlanes;
         // Was viewing window changed.
         mutable bool mRecalcWindow;
-        /// The last viewport to be added using this camera
-        Viewport* mLastViewport;
         /** Whether aspect ratio will automatically be recalculated 
             when a viewport changes its size
         */
@@ -579,16 +539,18 @@ namespace CamelotEngine {
 		vector<Vector4>::type getRayForwardIntersect(const Vector3& anchor, const Vector3 *dir, float planeOffset) const;
 
     public:
-        /** Standard constructor.
+		/** Standard constructor.
         */
-		Camera(RenderTarget* target,
-			float left = 0.0f, float top = 0.0f,
-			float width = 1.0f, float height = 1.0f,
-			int ZOrder = 0);
+		Camera(GameObjectPtr parent);
 
         /** Standard destructor.
         */
-        ~Camera();
+        virtual ~Camera();
+
+		void init(RenderTarget* target = nullptr,
+			float left = 0.0f, float top = 0.0f,
+			float width = 1.0f, float height = 1.0f,
+			int ZOrder = 0);
 
 		Viewport* getViewport() { return mViewport; }
 
@@ -605,160 +567,12 @@ namespace CamelotEngine {
         */
         PolygonMode getPolygonMode(void) const;
 
-        /** Sets the camera's position.
-        */
-        void setPosition(float x, float y, float z);
-
-        /** Sets the camera's position.
-        */
-        void setPosition(const Vector3& vec);
-
-        /** Retrieves the camera's position.
-        */
-        const Vector3& getPosition(void) const;
-
-        /** Moves the camera's position by the vector offset provided along world axes.
-        */
-        void move(const Vector3& vec);
-
-        /** Moves the camera's position by the vector offset provided along it's own axes (relative to orientation).
-        */
-        void moveRelative(const Vector3& vec);
-
-        /** Sets the camera's direction vector.
-            @remarks
-                Note that the 'up' vector for the camera will automatically be recalculated based on the
-                current 'up' vector (i.e. the roll will remain the same).
-        */
-        void setDirection(float x, float y, float z);
-
-        /** Sets the camera's direction vector.
-        */
-        void setDirection(const Vector3& vec);
-
-        /* Gets the camera's direction.
-        */
-        Vector3 getDirection(void) const;
-
-        /** Gets the camera's up vector.
-        */
-        Vector3 getUp(void) const;
-
-        /** Gets the camera's right vector.
-        */
-        Vector3 getRight(void) const;
-
-        /** Points the camera at a location in worldspace.
-            @remarks
-                This is a helper method to automatically generate the
-                direction vector for the camera, based on it's current position
-                and the supplied look-at point.
-            @param
-                targetPoint A vector specifying the look at point.
-        */
-        void lookAt( const Vector3& targetPoint );
-        /** Points the camera at a location in worldspace.
-            @remarks
-                This is a helper method to automatically generate the
-                direction vector for the camera, based on it's current position
-                and the supplied look-at point.
-            @param
-                x
-            @param
-                y
-            @param
-                z Co-ordinates of the point to look at.
-        */
-        void lookAt(float x, float y, float z);
-
-        /** Rolls the camera anticlockwise, around its local z axis.
-        */
-        void roll(const Radian& angle);
-
-        /** Rotates the camera anticlockwise around it's local y axis.
-        */
-        void yaw(const Radian& angle);
-
-        /** Pitches the camera up/down anticlockwise around it's local z axis.
-        */
-        void pitch(const Radian& angle);
-
-        /** Rotate the camera around an arbitrary axis.
-        */
-        void rotate(const Vector3& axis, const Radian& angle);
-
-        /** Rotate the camera around an arbitrary axis using a Quaternion.
-        */
-        void rotate(const Quaternion& q);
-
-        /** Tells the camera whether to yaw around it's own local Y axis or a 
-			fixed axis of choice.
-            @remarks
-                This method allows you to change the yaw behaviour of the camera
-				- by default, the camera yaws around a fixed Y axis. This is 
-				often what you want - for example if you're making a first-person 
-				shooter, you really don't want the yaw axis to reflect the local 
-				camera Y, because this would mean a different yaw axis if the 
-				player is looking upwards rather than when they are looking
-                straight ahead. You can change this behaviour by calling this 
-				method, which you will want to do if you are making a completely
-				free camera like the kind used in a flight simulator. 
-            @param
-                useFixed If true, the axis passed in the second parameter will 
-				always be the yaw axis no matter what the camera orientation. 
-				If false, the camera yaws around the local Y.
-            @param
-                fixedAxis The axis to use if the first parameter is true.
-        */
-        void setFixedYawAxis( bool useFixed, const Vector3& fixedAxis = Vector3::UNIT_Y );
-
-
-        /** Returns the camera's current orientation.
-        */
-        const Quaternion& getOrientation(void) const;
-
-        /** Sets the camera's orientation.
-        */
-        void setOrientation(const Quaternion& q);
-
         /** Tells the Camera to contact the SceneManager to render from it's viewpoint.
         @param vp The viewport to render to
         @param includeOverlays Whether or not any overlay objects should be included
         */
         void _renderScene(Viewport *vp, bool includeOverlays);
 
-        /** Gets the derived orientation of the camera, including any
-            rotation inherited from a node attachment and reflection matrix. */
-        const Quaternion& getDerivedOrientation(void) const;
-        /** Gets the derived position of the camera, including any
-            translation inherited from a node attachment and reflection matrix. */
-        const Vector3& getDerivedPosition(void) const;
-        /** Gets the derived direction vector of the camera, including any
-            rotation inherited from a node attachment and reflection matrix. */
-        Vector3 getDerivedDirection(void) const;
-        /** Gets the derived up vector of the camera, including any
-            rotation inherited from a node attachment and reflection matrix. */
-        Vector3 getDerivedUp(void) const;
-        /** Gets the derived right vector of the camera, including any
-            rotation inherited from a node attachment and reflection matrix. */
-        Vector3 getDerivedRight(void) const;
-
-        /** Gets the real world orientation of the camera, including any
-            rotation inherited from a node attachment */
-        const Quaternion& getRealOrientation(void) const;
-        /** Gets the real world position of the camera, including any
-            translation inherited from a node attachment. */
-        const Vector3& getRealPosition(void) const;
-        /** Gets the real world direction vector of the camera, including any
-            rotation inherited from a node attachment. */
-        Vector3 getRealDirection(void) const;
-        /** Gets the real world up vector of the camera, including any
-            rotation inherited from a node attachment. */
-        Vector3 getRealUp(void) const;
-        /** Gets the real world right vector of the camera, including any
-            rotation inherited from a node attachment. */
-        Vector3 getRealRight(void) const;
-
         /** Gets a world space ray as cast from the camera through a viewport position.
         @param screenx, screeny The x and y position at which the ray should intersect the viewport, 
             in normalised screen coordinates [0,1]
@@ -787,15 +601,6 @@ namespace CamelotEngine {
         virtual bool isWindowSet(void) const { return mWindowSet; }
         /// Gets the window clip planes, only applicable if isWindowSet == true
         const vector<Plane>::type& getWindowPlanes(void) const;
-		
-        /** Get the last viewport which was attached to this camera. 
-        @note This is not guaranteed to be the only viewport which is
-        using this camera, just the last once which was created referring
-        to it.
-        */
-        Viewport* getViewport(void) const {return mLastViewport;}
-        /** Notifies this camera that a viewport is using it.*/
-        void _notifyViewport(Viewport* viewport) {mLastViewport = viewport;}
 
         /** If set to true a viewport that owns this frustum will be able to 
             recalculate the aspect ratio whenever the frustum is resized.
@@ -815,14 +620,6 @@ namespace CamelotEngine {
 		    Forward projection may lead to intersections at infinity.
 		*/
 		void forwardIntersect(const Plane& worldPlane, vector<Vector4>::type* intersect3d) const;
-
-		/** Synchronise core camera settings with another. 
-		@remarks
-			Copies the position, orientation, clip distances, projection type, 
-			FOV, focal length and aspect ratio from another camera. Other settings like query flags, 
-			reflection etc are preserved.
-		*/
-		void synchroniseBaseSettingsWith(const Camera* cam);
      };
 	 /** @} */
 	 /** @} */

+ 8 - 4
CamelotRenderer/Include/CmComponent.h

@@ -4,13 +4,17 @@
 
 namespace CamelotEngine
 {
-	class Component
+	class CM_EXPORT Component
 	{
-	private:
-		friend class GameObject;
+	public:
+		GameObjectPtr getGameObject() const { return mParent.lock(); }
 
+		// TODO - This shouldn't really be public since only GameObject should be allowed to add components.
+		// But then I have a problem that all derived classes need to have GameObject as a friend class.
 		Component(GameObjectPtr parent);
 		virtual ~Component();
+	protected:
+		friend class GameObject;
 
 		/**
 		 * @brief	Destroys the Component and makes it unusable, without actually deleting it.
@@ -19,7 +23,7 @@ namespace CamelotEngine
 		 */
 		void destroy();
 
-		GameObjectPtr mParent;
+		std::weak_ptr<GameObject> mParent;
 		bool mIsDestroyed;
 	};
 }

+ 22 - 13
CamelotRenderer/Include/CmGameObject.h

@@ -31,16 +31,21 @@ namespace CamelotEngine
 		/************************************************************************/
 	public:
 		void setPosition(const Vector3& position);
-		Vector3 getPosition() const { return mPosition; }
+		const Vector3& getPosition() const { return mPosition; }
+		const Vector3& getWorldPosition() const;
 
 		void setRotation(const Quaternion& rotation);
-		Quaternion getRotation() const { return mRotation; }
+		const Quaternion& getRotation() const { return mRotation; }
+		const Quaternion& getWorldRotation() const;
 
 		void setScale(const Vector3& scale);
-		Vector3 getScale() const { return mScale; }
+		const Vector3& getScale() const { return mScale; }
+		const Vector3& getWorldScale() const;
 
-		const Matrix4& getWorldTfrm();
-		const Matrix4& getLocalTfrm();
+		void lookAt(const Vector3& location, const Vector3& up = Vector3::UNIT_Y);
+
+		const Matrix4& getWorldTfrm() const;
+		const Matrix4& getLocalTfrm() const;
 
 	private:
 		String mName;
@@ -49,18 +54,22 @@ namespace CamelotEngine
 		Quaternion mRotation;
 		Vector3 mScale;
 
-		Matrix4 mCachedLocalTfrm;
-		bool mIsCachedLocalTfrmUpToDate;
+		mutable Vector3 mWorldPosition;
+		mutable Quaternion mWorldRotation;
+		mutable Vector3 mWorldScale;
+
+		mutable Matrix4 mCachedLocalTfrm;
+		mutable bool mIsCachedLocalTfrmUpToDate;
 
-		Matrix4 mCachedWorldTfrm;
-		bool mIsCachedWorldTfrmUpToDate;
+		mutable Matrix4 mCachedWorldTfrm;
+		mutable bool mIsCachedWorldTfrmUpToDate;
 
 		Matrix4 mCustomWorldTfrm; // TODO
 		bool mIsCustomTfrmModeActive; // TODO
 
-		void markTfrmDirty();
-		void updateLocalTfrm();
-		void updateWorldTfrm();
+		void markTfrmDirty() const;
+		void updateLocalTfrm() const;
+		void updateWorldTfrm() const;
 
 		/************************************************************************/
 		/* 								Hierarchy	                     		*/
@@ -137,7 +146,7 @@ namespace CamelotEngine
 			BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotEngine::Component, T>::value), 
 				"Specified type is not a valid Component.");
 
-			std::shared_ptr<T> newComponent = std::shared_ptr<T>(new T(this));
+			std::shared_ptr<T> newComponent = std::shared_ptr<T>(new T(mThis.lock()));
 			mComponents.push_back(newComponent);
 
 			return newComponent;

+ 7 - 3
CamelotRenderer/Source/CmApplication.cpp

@@ -16,6 +16,7 @@
 #include "CmSceneManager.h"
 #include "CmImporter.h"
 #include "CmResources.h"
+#include "CmGameObject.h"
 
 namespace CamelotEngine
 {
@@ -40,9 +41,12 @@ namespace CamelotEngine
 		//renderSystem->setAmbientLight(1.0f, 1.0f, 1.0f);
 		renderSystem->setLightingEnabled(false);
 
-		mCamera = new Camera(mRenderWindow, 0.0f, 0.0f, 1.0f, 1.0f, 0);
-		mCamera->setPosition(Vector3(0,0,40));
-		mCamera->lookAt(Vector3(0,0,-300));
+		mCameraGO = GameObject::create("MainCamera");
+		mCamera = mCameraGO->addComponent<Camera>();
+
+		mCamera->init(mRenderWindow, 0.0f, 0.0f, 1.0f, 1.0f, 0);
+		mCameraGO->setPosition(Vector3(0,0,40));
+		mCameraGO->lookAt(Vector3(0,0,-300));
 		mCamera->setNearClipDistance(5);
 		mCamera->setAspectRatio(600.0f / 800.0f);
 

+ 15 - 422
CamelotRenderer/Source/CmCamera.cpp

@@ -38,6 +38,7 @@ THE SOFTWARE.
 #include "CmRenderSystemManager.h"
 #include "CmException.h"
 #include "CmRenderSystem.h"
+#include "CmGameObject.h"
 
 #if CM_PLATFORM == OGRE_PLATFORM_IPHONE
 #include "macUtils.h"
@@ -47,11 +48,9 @@ namespace CamelotEngine {
 	const float Camera::INFINITE_FAR_PLANE_ADJUST = 0.00001f;
 
     //-----------------------------------------------------------------------
-	Camera::Camera(RenderTarget* target,
-		float left, float top,
-		float width, float height,
-		int ZOrder)
-        : mProjType(PT_PERSPECTIVE), 
+	Camera::Camera(GameObjectPtr parent)
+        : Component(parent),
+		mProjType(PT_PERSPECTIVE), 
 		mFOVy(Radian(Math::PI/4.0f)), 
 		mFarDist(100000.0f), 
 		mNearDist(100.0f), 
@@ -62,19 +61,16 @@ namespace CamelotEngine {
 		mLastParentOrientation(Quaternion::IDENTITY),
 		mLastParentPosition(Vector3::ZERO),
 		mRecalcFrustum(true), 
-		mRecalcView(true), 
 		mRecalcFrustumPlanes(true),
 		mRecalcWorldSpaceCorners(true),
 		mRecalcVertexData(true),
 		mCustomViewMatrix(false),
 		mCustomProjMatrix(false),
 		mFrustumExtentsManuallySet(false),
-		mOrientation(Quaternion::IDENTITY),
-		mPosition(Vector3::ZERO),
 		mSceneDetail(PM_SOLID),
 		mWindowSet(false),
-		mLastViewport(0),
-		mAutoAspectRatio(false)
+		mAutoAspectRatio(false),
+		mViewport(nullptr)
     {
 		updateView();
 		updateFrustum();
@@ -85,16 +81,12 @@ namespace CamelotEngine {
         mFarDist = 100000.0f;
         mAspect = 1.33333333333333f;
         mProjType = PT_PERSPECTIVE;
-        setFixedYawAxis(true);    // Default to fixed yaw, like freelook since most people expect this
 
         invalidateFrustum();
-        invalidateView();
 
         // Init matrices
         mViewMatrix = Matrix4::ZERO;
         mProjMatrixRS = Matrix4::ZERO;
-
-		mViewport = new Viewport(target, left, top, width, height, ZOrder);
     }
 
     //-----------------------------------------------------------------------
@@ -103,6 +95,10 @@ namespace CamelotEngine {
 		if(mViewport != nullptr)
 			delete mViewport;
     }
+	void Camera::init(RenderTarget* target, float left, float top, float width, float height, int ZOrder)
+	{
+		mViewport = new Viewport(target, left, top, width, height, ZOrder);
+	}
 	//-----------------------------------------------------------------------
 	void Camera::setFOVy(const Radian& fov)
 	{
@@ -657,49 +653,18 @@ namespace CamelotEngine {
 	{
 		return mRecalcFrustum;
 	}
-
 	//-----------------------------------------------------------------------
-	void Camera::updateViewImpl(void) const
+	void Camera::updateView(void) const
 	{
-		// ----------------------
-		// Update the view matrix
-		// ----------------------
-
-		// Get orientation from quaternion
-
 		if (!mCustomViewMatrix)
 		{
 			Matrix3 rot;
-			const Quaternion& orientation = getOrientationForViewUpdate();
-			const Vector3& position = getPositionForViewUpdate();
+			const Quaternion& orientation = getGameObject()->getWorldRotation();
+			const Vector3& position = getGameObject()->getWorldPosition();
 
 			mViewMatrix = Math::makeViewMatrix(position, orientation, 0);
 		}
-
-		mRecalcView = false;
-
-		// Signal to update frustum clipping planes
-		mRecalcFrustumPlanes = true;
-		// Signal to update world space corners
-		mRecalcWorldSpaceCorners = true;
-	}
-	//---------------------------------------------------------------------
-	void Camera::calcViewMatrixRelative(const Vector3& relPos, Matrix4& matToUpdate) const
-	{
-		Matrix4 matTrans = Matrix4::IDENTITY;
-		matTrans.setTrans(relPos);
-		matToUpdate = getViewMatrix() * matTrans;
-
-	}
-	//-----------------------------------------------------------------------
-	void Camera::updateView(void) const
-	{
-		if (isViewOutOfDate())
-		{
-			updateViewImpl();
-		}
 	}
-
 	//-----------------------------------------------------------------------
 	void Camera::updateFrustumPlanesImpl(void) const
 	{
@@ -1021,7 +986,6 @@ namespace CamelotEngine {
 			assert(viewMatrix.isAffine());
 			mViewMatrix = viewMatrix;
 		}
-		invalidateView();
 	}
 	//---------------------------------------------------------------------
 	void Camera::setCustomProjectionMatrix(bool enable, const Matrix4& projMatrix)
@@ -1099,265 +1063,6 @@ namespace CamelotEngine {
     {
         return mSceneDetail;
     }
-
-    //-----------------------------------------------------------------------
-    void Camera::setPosition(float x, float y, float z)
-    {
-        mPosition.x = x;
-        mPosition.y = y;
-        mPosition.z = z;
-        invalidateView();
-    }
-
-    //-----------------------------------------------------------------------
-    void Camera::setPosition(const Vector3& vec)
-    {
-        mPosition = vec;
-        invalidateView();
-    }
-
-    //-----------------------------------------------------------------------
-    const Vector3& Camera::getPosition(void) const
-    {
-        return mPosition;
-    }
-
-    //-----------------------------------------------------------------------
-    void Camera::move(const Vector3& vec)
-    {
-        mPosition = mPosition + vec;
-        invalidateView();
-    }
-
-    //-----------------------------------------------------------------------
-    void Camera::moveRelative(const Vector3& vec)
-    {
-        // Transform the axes of the relative vector by camera's local axes
-        Vector3 trans = mOrientation * vec;
-
-        mPosition = mPosition + trans;
-        invalidateView();
-    }
-
-    //-----------------------------------------------------------------------
-    void Camera::setDirection(float x, float y, float z)
-    {
-        setDirection(Vector3(x,y,z));
-    }
-
-    //-----------------------------------------------------------------------
-    void Camera::setDirection(const Vector3& vec)
-    {
-        // Do nothing if given a zero vector
-        // (Replaced assert since this could happen with auto tracking camera and
-        //  camera passes through the lookAt point)
-        if (vec == Vector3::ZERO) return;
-
-        // Remember, camera points down -Z of local axes!
-        // Therefore reverse direction of direction vector before determining local Z
-        Vector3 zAdjustVec = -vec;
-        zAdjustVec.normalise();
-
-		Quaternion targetWorldOrientation;
-
-
-        if( mYawFixed )
-        {
-            Vector3 xVec = mYawFixedAxis.crossProduct( zAdjustVec );
-            xVec.normalise();
-
-            Vector3 yVec = zAdjustVec.crossProduct( xVec );
-            yVec.normalise();
-
-            targetWorldOrientation.FromAxes( xVec, yVec, zAdjustVec );
-        }
-        else
-        {
-
-            // Get axes from current quaternion
-            Vector3 axes[3];
-            updateView();
-            mRealOrientation.ToAxes(axes);
-            Quaternion rotQuat;
-            if ( (axes[2]+zAdjustVec).squaredLength() <  0.00005f) 
-            {
-                // Oops, a 180 degree turn (infinite possible rotation axes)
-                // Default to yaw i.e. use current UP
-                rotQuat.FromAngleAxis(Radian(Math::PI), axes[1]);
-            }
-            else
-            {
-                // Derive shortest arc to new direction
-                rotQuat = axes[2].getRotationTo(zAdjustVec);
-
-            }
-            targetWorldOrientation = rotQuat * mRealOrientation;
-        }
-
-        // transform to parent space
-		// TODO PORT -  Can't get orientation from parent until we hook it up properly as a Component
-  //      if (mParentNode)
-  //      {
-  //          mOrientation =
-  //              mParentNode->_getDerivedOrientation().Inverse() * targetWorldOrientation;
-  //      }
-		//else
-		{
-			mOrientation = targetWorldOrientation;
-		}
-
-        // TODO If we have a fixed yaw axis, we mustn't break it by using the
-        // shortest arc because this will sometimes cause a relative yaw
-        // which will tip the camera
-
-        invalidateView();
-
-    }
-
-    //-----------------------------------------------------------------------
-    Vector3 Camera::getDirection(void) const
-    {
-        // Direction points down -Z by default
-        return mOrientation * -Vector3::UNIT_Z;
-    }
-
-    //-----------------------------------------------------------------------
-    Vector3 Camera::getUp(void) const
-    {
-        return mOrientation * Vector3::UNIT_Y;
-    }
-
-    //-----------------------------------------------------------------------
-    Vector3 Camera::getRight(void) const
-    {
-        return mOrientation * Vector3::UNIT_X;
-    }
-
-    //-----------------------------------------------------------------------
-    void Camera::lookAt(const Vector3& targetPoint)
-    {
-        updateView();
-        this->setDirection(targetPoint - mRealPosition);
-    }
-
-    //-----------------------------------------------------------------------
-    void Camera::lookAt( float x, float y, float z )
-    {
-        Vector3 vTemp( x, y, z );
-        this->lookAt(vTemp);
-    }
-
-    //-----------------------------------------------------------------------
-    void Camera::roll(const Radian& angle)
-    {
-        // Rotate around local Z axis
-        Vector3 zAxis = mOrientation * Vector3::UNIT_Z;
-        rotate(zAxis, angle);
-
-        invalidateView();
-    }
-
-    //-----------------------------------------------------------------------
-    void Camera::yaw(const Radian& angle)
-    {
-        Vector3 yAxis;
-
-        if (mYawFixed)
-        {
-            // Rotate around fixed yaw axis
-            yAxis = mYawFixedAxis;
-        }
-        else
-        {
-            // Rotate around local Y axis
-            yAxis = mOrientation * Vector3::UNIT_Y;
-        }
-
-        rotate(yAxis, angle);
-
-        invalidateView();
-    }
-
-    //-----------------------------------------------------------------------
-    void Camera::pitch(const Radian& angle)
-    {
-        // Rotate around local X axis
-        Vector3 xAxis = mOrientation * Vector3::UNIT_X;
-        rotate(xAxis, angle);
-
-        invalidateView();
-
-    }
-
-    //-----------------------------------------------------------------------
-    void Camera::rotate(const Vector3& axis, const Radian& angle)
-    {
-        Quaternion q;
-        q.FromAngleAxis(angle,axis);
-        rotate(q);
-    }
-
-    //-----------------------------------------------------------------------
-    void Camera::rotate(const Quaternion& q)
-    {
-        // Note the order of the mult, i.e. q comes after
-
-		// Normalise the quat to avoid cumulative problems with precision
-		Quaternion qnorm = q;
-		qnorm.normalise();
-        mOrientation = qnorm * mOrientation;
-
-        invalidateView();
-
-    }
-
-    //-----------------------------------------------------------------------
-    bool Camera::isViewOutOfDate(void) const
-    {
-        // Overridden from Frustum to use local orientation / position offsets
-        // Attached to node?
-		// TODO PORT -  Can't get orientation/position from parent until we hook it up properly as a Component
-        //if (mParentNode != 0)
-        //{
-        //    if (mRecalcView ||
-        //        mParentNode->_getDerivedOrientation() != mLastParentOrientation ||
-        //        mParentNode->_getDerivedPosition() != mLastParentPosition)
-        //    {
-        //        // Ok, we're out of date with SceneNode we're attached to
-        //        mLastParentOrientation = mParentNode->_getDerivedOrientation();
-        //        mLastParentPosition = mParentNode->_getDerivedPosition();
-        //        mRealOrientation = mLastParentOrientation * mOrientation;
-        //        mRealPosition = (mLastParentOrientation * mPosition) + mLastParentPosition;
-        //        mRecalcView = true;
-        //        mRecalcWindow = true;
-        //    }
-        //}
-        //else
-        {
-            // Rely on own updates
-            mRealOrientation = mOrientation;
-            mRealPosition = mPosition;
-        }
-
-        // Deriving reflected orientation / position
-        if (mRecalcView)
-        {
-			mDerivedOrientation = mRealOrientation;
-			mDerivedPosition = mRealPosition;
-        }
-
-        return mRecalcView;
-
-    }
-
-    // -------------------------------------------------------------------
-    void Camera::invalidateView() const
-    {
-        mRecalcWindow = true;
-		mRecalcView = true;
-		mRecalcFrustumPlanes = true;
-		mRecalcWorldSpaceCorners = true;
-    }
     // -------------------------------------------------------------------
     void Camera::invalidateFrustum(void) const
     {
@@ -1373,88 +1078,6 @@ namespace CamelotEngine {
 		// TODO PORT - I'm not going to be rendering the scene like this (yet), but I think I will do it eventually
         //mSceneMgr->_renderScene(this, vp, includeOverlays);
 	}
-
-    //-----------------------------------------------------------------------
-    void Camera::setFixedYawAxis(bool useFixed, const Vector3& fixedAxis)
-    {
-        mYawFixed = useFixed;
-        mYawFixedAxis = fixedAxis;
-    }
-    //-----------------------------------------------------------------------
-    const Quaternion& Camera::getOrientation(void) const
-    {
-        return mOrientation;
-    }
-
-    //-----------------------------------------------------------------------
-    void Camera::setOrientation(const Quaternion& q)
-    {
-        mOrientation = q;
-		mOrientation.normalise();
-        invalidateView();
-    }
-    //-----------------------------------------------------------------------
-    const Quaternion& Camera::getDerivedOrientation(void) const
-    {
-        updateView();
-        return mDerivedOrientation;
-    }
-    //-----------------------------------------------------------------------
-    const Vector3& Camera::getDerivedPosition(void) const
-    {
-        updateView();
-        return mDerivedPosition;
-    }
-    //-----------------------------------------------------------------------
-    Vector3 Camera::getDerivedDirection(void) const
-    {
-        // Direction points down -Z
-        updateView();
-        return mDerivedOrientation * Vector3::NEGATIVE_UNIT_Z;
-    }
-    //-----------------------------------------------------------------------
-    Vector3 Camera::getDerivedUp(void) const
-    {
-        updateView();
-        return mDerivedOrientation * Vector3::UNIT_Y;
-    }
-    //-----------------------------------------------------------------------
-    Vector3 Camera::getDerivedRight(void) const
-    {
-        updateView();
-        return mDerivedOrientation * Vector3::UNIT_X;
-    }
-    //-----------------------------------------------------------------------
-    const Quaternion& Camera::getRealOrientation(void) const
-    {
-        updateView();
-        return mRealOrientation;
-    }
-    //-----------------------------------------------------------------------
-    const Vector3& Camera::getRealPosition(void) const
-    {
-        updateView();
-        return mRealPosition;
-    }
-    //-----------------------------------------------------------------------
-    Vector3 Camera::getRealDirection(void) const
-    {
-        // Direction points down -Z
-        updateView();
-        return mRealOrientation * Vector3::NEGATIVE_UNIT_Z;
-    }
-    //-----------------------------------------------------------------------
-    Vector3 Camera::getRealUp(void) const
-    {
-        updateView();
-        return mRealOrientation * Vector3::UNIT_Y;
-    }
-    //-----------------------------------------------------------------------
-    Vector3 Camera::getRealRight(void) const
-    {
-        updateView();
-        return mRealOrientation * Vector3::UNIT_X;
-    }
     //-----------------------------------------------------------------------
 	Ray Camera::getCameraToViewportRay(float screenX, float screenY) const
 	{
@@ -1534,7 +1157,7 @@ namespace CamelotEngine {
 		mWindowClipPlanes.clear();
         if (mProjType == PT_PERSPECTIVE)
         {
-            Vector3 position = getPositionForViewUpdate();
+            Vector3 position = getGameObject()->getWorldPosition();
             mWindowClipPlanes.push_back(Plane(position, vw_bl, vw_ul));
             mWindowClipPlanes.push_back(Plane(position, vw_ul, vw_ur));
             mWindowClipPlanes.push_back(Plane(position, vw_ur, vw_br));
@@ -1571,17 +1194,6 @@ namespace CamelotEngine {
 
     }
     //-----------------------------------------------------------------------
-    const Vector3& Camera::getPositionForViewUpdate(void) const
-    {
-        // Note no update, because we're calling this from the update!
-        return mRealPosition;
-    }
-    //-----------------------------------------------------------------------
-    const Quaternion& Camera::getOrientationForViewUpdate(void) const
-    {
-        return mRealOrientation;
-    }
-    //-----------------------------------------------------------------------
     bool Camera::getAutoAspectRatio(void) const
     {
         return mAutoAspectRatio;
@@ -1706,7 +1318,7 @@ namespace CamelotEngine {
 		Quaternion invPlaneRot = pval.normal.getRotationTo(Vector3::UNIT_Z);
 
 		// get rotated light
-		Vector3 lPos = invPlaneRot * getDerivedPosition();
+		Vector3 lPos = invPlaneRot * getGameObject()->getWorldPosition();
 		Vector3 vec[4];
 		vec[0] = invPlaneRot * trCorner - lPos;
 		vec[1] = invPlaneRot * tlCorner - lPos; 
@@ -1729,23 +1341,4 @@ namespace CamelotEngine {
 			}
 		}
 	}
-	//-----------------------------------------------------------------------
-	void Camera::synchroniseBaseSettingsWith(const Camera* cam)
-	{
-		this->setPosition(cam->getPosition());
-		this->setProjectionType(cam->getProjectionType());
-		this->setOrientation(cam->getOrientation());
-		this->setAspectRatio(cam->getAspectRatio());
-		this->setNearClipDistance(cam->getNearClipDistance());
-		this->setFarClipDistance(cam->getFarClipDistance());
-		this->setFOVy(cam->getFOVy());
-		this->setFocalLength(cam->getFocalLength());
-
-		// Don't do these, they're not base settings and can cause referencing issues
-		//this->setLodCamera(cam->getLodCamera());
-		//this->setCullingFrustum(cam->getCullingFrustum());
-
-	}
-
-
 } // namespace CamelotEngine

+ 0 - 1
CamelotRenderer/Source/CmComponent.cpp

@@ -17,6 +17,5 @@ namespace CamelotEngine
 	void Component::destroy()
 	{
 		mIsDestroyed = true;
-		mParent = nullptr;
 	}
 }

+ 75 - 7
CamelotRenderer/Source/CmGameObject.cpp

@@ -7,7 +7,8 @@
 namespace CamelotEngine
 {
 	GameObject::GameObject(const String& name)
-		:mName(name), mPosition(Vector3::ZERO), mRotation(Quaternion::IDENTITY), mScale(Vector3::ZERO),
+		:mName(name), mPosition(Vector3::ZERO), mRotation(Quaternion::IDENTITY), mScale(Vector3::UNIT_SCALE),
+		mWorldPosition(Vector3::ZERO), mWorldRotation(Quaternion::IDENTITY), mWorldScale(Vector3::UNIT_SCALE),
 		mCachedLocalTfrm(Matrix4::IDENTITY), mIsCachedLocalTfrmUpToDate(false),
 		mCachedWorldTfrm(Matrix4::IDENTITY), mIsCachedWorldTfrmUpToDate(false),
 		mCustomWorldTfrm(Matrix4::IDENTITY), mIsCustomTfrmModeActive(false),
@@ -84,7 +85,48 @@ namespace CamelotEngine
 		markTfrmDirty();
 	}
 
-	const Matrix4& GameObject::getWorldTfrm()
+	const Vector3& GameObject::getWorldPosition() const
+	{ 
+		if(!mIsCachedWorldTfrmUpToDate)
+			updateWorldTfrm();
+
+		return mWorldPosition; 
+	}
+
+	const Quaternion& GameObject::getWorldRotation() const 
+	{ 
+		if(!mIsCachedWorldTfrmUpToDate)
+			updateWorldTfrm();
+
+		return mWorldRotation; 
+	}
+
+	const Vector3& GameObject::getWorldScale() const 
+	{ 
+		if(!mIsCachedWorldTfrmUpToDate)
+			updateWorldTfrm();
+
+		return mWorldScale; 
+	}
+
+	void GameObject::lookAt(const Vector3& location, const Vector3& up)
+	{
+		Vector3 forward = location - mPosition;
+		forward.normalise();
+
+		Vector3 upCopy = up;
+		upCopy.normalise();
+
+		Vector3 right = forward.crossProduct(up);
+		right.normalise();
+
+		Quaternion newRotation;
+		newRotation.FromAxes(right, upCopy, forward);
+
+		setRotation(newRotation);
+	}
+
+	const Matrix4& GameObject::getWorldTfrm() const
 	{
 		if(!mIsCachedWorldTfrmUpToDate)
 			updateWorldTfrm();
@@ -92,7 +134,7 @@ namespace CamelotEngine
 		return mCachedWorldTfrm;
 	}
 
-	const Matrix4& GameObject::getLocalTfrm()
+	const Matrix4& GameObject::getLocalTfrm() const
 	{
 		if(!mIsCachedLocalTfrmUpToDate)
 			updateLocalTfrm();
@@ -100,7 +142,7 @@ namespace CamelotEngine
 		return mCachedLocalTfrm;
 	}
 
-	void GameObject::markTfrmDirty()
+	void GameObject::markTfrmDirty() const
 	{
 		mIsCachedLocalTfrmUpToDate = false;
 
@@ -115,17 +157,43 @@ namespace CamelotEngine
 		}
 	}
 
-	void GameObject::updateWorldTfrm()
+	void GameObject::updateWorldTfrm() const
 	{
 		if(!mParent.expired())
-			mCachedWorldTfrm = getLocalTfrm() * mParent.lock()->getWorldTfrm();
+		{
+			GameObjectPtr tempParentPtr = mParent.lock();
+
+			mCachedWorldTfrm = getLocalTfrm() * tempParentPtr->getWorldTfrm();
+
+			// Update orientation
+			const Quaternion& parentOrientation = tempParentPtr->getWorldRotation();
+			mWorldRotation = parentOrientation * mRotation;
+
+			// Update scale
+			const Vector3& parentScale = tempParentPtr->getWorldScale();
+			// Scale own position by parent scale, NB just combine
+			// as equivalent axes, no shearing
+			mWorldScale = parentScale * mScale;
+
+			// Change position vector based on parent's orientation & scale
+			mWorldPosition = parentOrientation * (parentScale * mPosition);
+
+			// Add altered position vector to parents
+			mWorldPosition += tempParentPtr->getWorldPosition();
+		}
 		else
+		{
 			mCachedWorldTfrm = getLocalTfrm();
 
+			mWorldRotation = mRotation;
+			mWorldPosition = mPosition;
+			mWorldScale = mScale;
+		}
+
 		mIsCachedWorldTfrmUpToDate = true;
 	}
 
-	void GameObject::updateLocalTfrm()
+	void GameObject::updateLocalTfrm() const
 	{
 		mCachedLocalTfrm.makeTransform(mPosition, mScale, mRotation);
 

+ 9 - 6
CamelotRenderer/Source/CmViewport.cpp

@@ -58,13 +58,16 @@ namespace CamelotEngine {
     //---------------------------------------------------------------------
     void Viewport::_updateDimensions(void)
     {
-        float height = (float) mTarget->getHeight();
-        float width = (float) mTarget->getWidth();
+		if(mTarget != nullptr)
+		{
+			float height = (float) mTarget->getHeight();
+			float width = (float) mTarget->getWidth();
 
-        mActLeft = (int) (mRelLeft * width);
-        mActTop = (int) (mRelTop * height);
-        mActWidth = (int) (mRelWidth * width);
-        mActHeight = (int) (mRelHeight * height);
+			mActLeft = (int) (mRelLeft * width);
+			mActTop = (int) (mRelTop * height);
+			mActWidth = (int) (mRelWidth * width);
+			mActHeight = (int) (mRelHeight * height);
+		}
     }
 	//---------------------------------------------------------------------
 	int Viewport::getZOrder(void) const