Przeglądaj źródła

Joint gizmos (not tested)

BearishSun 9 lat temu
rodzic
commit
f92aa5938f

+ 257 - 255
Source/BansheeCore/Source/BsCJoint.cpp

@@ -1,256 +1,258 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-#include "BsCJoint.h"
-#include "BsCRigidbody.h"
-#include "BsSceneObject.h"
-#include "BsPhysics.h"
-#include "BsCJointRTTI.h"
-
-using namespace std::placeholders;
-
-namespace BansheeEngine
-{
-	CJoint::CJoint(const HSceneObject& parent)
-		: Component(parent)
-	{
-		setName("Joint");
-
-		mNotifyFlags = (TransformChangedFlags)(TCF_Parent | TCF_Transform);
-	}
-
-	HRigidbody CJoint::getBody(JointBody body) const
-	{
-		return mBodies[(int)body];
-	}
-
-	void CJoint::setBody(JointBody body, const HRigidbody& value)
-	{
-		if (mBodies[(int)body] == value)
-			return;
-
-		if (mBodies[(int)body] != nullptr)
-			mBodies[(int)body]->_setJoint(HJoint());
-
-		mBodies[(int)body] = value;
-
-		if (value != nullptr)
-			mBodies[(int)body]->_setJoint(mThisHandle);
-
-		if(mInternal != nullptr)
-		{
-			Rigidbody* rigidbody = nullptr;
-			if (value != nullptr)
-				rigidbody = value->_getInternal();
-
-			mInternal->setBody(body, rigidbody);
-			updateTransform(body);
-		}
-	}
-
-	Vector3 CJoint::getPosition(JointBody body) const
-	{
-		return mPositions[(int)body];
-	}
-
-	Quaternion CJoint::getRotation(JointBody body) const
-	{
-		return mRotations[(int)body];
-	}
-
-	void CJoint::setTransform(JointBody body, const Vector3& position, const Quaternion& rotation)
-	{
-		if (mPositions[(int)body] == position && mRotations[(int)body] == rotation)
-			return;
-
-		mPositions[(int)body] = position;
-		mRotations[(int)body] = rotation;
-
-		if(mInternal != nullptr)
-			updateTransform(body);
-	}
-
-	float CJoint::getBreakForce() const
-	{
-		return mBreakForce;
-	}
-
-	void CJoint::setBreakForce(float force)
-	{
-		if (mBreakForce == force)
-			return;
-
-		mBreakForce = force;
-
-		if (mInternal != nullptr)
-			mInternal->setBreakForce(force);
-	}
-
-	float CJoint::getBreakTorque() const
-	{
-		return mBreakTorque;
-	}
-
-	void CJoint::setBreakToque(float torque)
-	{
-		if (mBreakTorque == torque)
-			return;
-
-		mBreakTorque = torque;
-
-		if (mInternal != nullptr)
-			mInternal->setBreakTorque(torque);
-	}
-
-	bool CJoint::getEnableCollision() const
-	{
-		return mEnableCollision;
-	}
-
-	void CJoint::setEnableCollision(bool value)
-	{
-		if (mEnableCollision == value)
-			return;
-
-		mEnableCollision = value;
-
-		if (mInternal != nullptr)
-			mInternal->setEnableCollision(value);
-	}
-
-	void CJoint::onInitialized()
-	{
-
-	}
-
-	void CJoint::onDestroyed()
-	{
-		if (mBodies[0] != nullptr)
-			mBodies[0]->_setJoint(HJoint());
-
-		if (mBodies[1] != nullptr)
-			mBodies[1]->_setJoint(HJoint());
-
-		destroyInternal();
-	}
-
-	void CJoint::onDisabled()
-	{
-		destroyInternal();
-	}
-
-	void CJoint::onEnabled()
-	{
-		restoreInternal();
-	}
-
-	void CJoint::onTransformChanged(TransformChangedFlags flags)
-	{
-		if (!SO()->getActive())
-			return;
-
-		// We're ignoring this during physics update because it would cause problems if the joint itself was moved by physics
-		// Note: This isn't particularily correct because if the joint is being moved by physics but the rigidbodies
-		// themselves are not parented to the joint, the transform will need updating. However I'm leaving it up to the
-		// user to ensure rigidbodies are always parented to the joint in such a case (It's an unlikely situation that
-		// I can't think of an use for - joint transform will almost always be set as an initialization step and not a 
-		// physics response).
-		if (gPhysics()._isUpdateInProgress())
-			return;
-
-		updateTransform(JointBody::A);
-		updateTransform(JointBody::B);
-	}
-
-	void CJoint::restoreInternal()
-	{
-		if (mInternal == nullptr)
-		{
-			mInternal = createInternal();
-
-			mInternal->onJointBreak.connect(std::bind(&CJoint::triggerOnJointBroken, this));
-		}
-
-		// Note: Merge into one call to avoid many virtual function calls
-		Rigidbody* bodies[2];
-
-		if (mBodies[0] != nullptr)
-			bodies[0] = mBodies[0]->_getInternal();
-		else
-			bodies[0] = nullptr;
-
-		if (mBodies[1] != nullptr)
-			bodies[1] = mBodies[1]->_getInternal();
-		else
-			bodies[1] = nullptr;
-
-		mInternal->setBody(JointBody::A, bodies[0]);
-		mInternal->setBody(JointBody::B, bodies[1]);
-		mInternal->setBreakForce(mBreakForce);
-		mInternal->setBreakTorque(mBreakTorque);
-		mInternal->setEnableCollision(mEnableCollision);
-
-		updateTransform(JointBody::A);
-		updateTransform(JointBody::B);
-	}
-
-	void CJoint::destroyInternal()
-	{
-		// This should release the last reference and destroy the internal joint
-		mInternal->_setOwner(PhysicsOwnerType::None, nullptr);
-		mInternal = nullptr;
-	}
-
-	void CJoint::notifyRigidbodyMoved(const HRigidbody& body)
-	{
-		// If physics update is in progress do nothing, as its the joint itself that's probably moving the body
-		if (gPhysics()._isUpdateInProgress())
-			return;
-
-		if (mBodies[0] == body)
-			updateTransform(JointBody::A);
-		else if (mBodies[1] == body)
-			updateTransform(JointBody::B);
-		else
-			assert(false); // Not allowed to happen
-	}
-
-	void CJoint::updateTransform(JointBody body)
-	{
-		Vector3 localPos;
-		Quaternion localRot;
-
-		localPos = mPositions[(int)body];
-		localRot = mRotations[(int)body];
-
-		// Transform to world space of the related body
-		HRigidbody rigidbody = mBodies[(int)body];
-		if (rigidbody != nullptr)
-		{
-			localRot = rigidbody->SO()->getWorldRotation() * localRot;
-			localPos = localRot.rotate(localPos) + rigidbody->SO()->getWorldPosition();
-		}
-
-		// Transform to space local to the joint
-		Quaternion invRotation = SO()->getWorldRotation().inverse();
-
-		localPos = invRotation.rotate(localPos - SO()->getWorldPosition());
-		localRot = invRotation * localRot;
-
-		mInternal->setTransform(body, localPos, localRot);
-	}
-	
-	void CJoint::triggerOnJointBroken()
-	{
-		onJointBreak();
-	}
-
-	RTTITypeBase* CJoint::getRTTIStatic()
-	{
-		return CJointRTTI::instance();
-	}
-
-	RTTITypeBase* CJoint::getRTTI() const
-	{
-		return CJoint::getRTTIStatic();
-	}
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "BsCJoint.h"
+#include "BsCRigidbody.h"
+#include "BsSceneObject.h"
+#include "BsPhysics.h"
+#include "BsCJointRTTI.h"
+
+using namespace std::placeholders;
+
+namespace BansheeEngine
+{
+	CJoint::CJoint(const HSceneObject& parent)
+		: Component(parent)
+	{
+		setName("Joint");
+
+		mNotifyFlags = (TransformChangedFlags)(TCF_Parent | TCF_Transform);
+	}
+
+	HRigidbody CJoint::getBody(JointBody body) const
+	{
+		return mBodies[(int)body];
+	}
+
+	void CJoint::setBody(JointBody body, const HRigidbody& value)
+	{
+		if (mBodies[(int)body] == value)
+			return;
+
+		if (mBodies[(int)body] != nullptr)
+			mBodies[(int)body]->_setJoint(HJoint());
+
+		mBodies[(int)body] = value;
+
+		if (value != nullptr)
+			mBodies[(int)body]->_setJoint(mThisHandle);
+
+		if(mInternal != nullptr)
+		{
+			Rigidbody* rigidbody = nullptr;
+			if (value != nullptr)
+				rigidbody = value->_getInternal();
+
+			mInternal->setBody(body, rigidbody);
+			updateTransform(body);
+		}
+	}
+
+	Vector3 CJoint::getPosition(JointBody body) const
+	{
+		return mPositions[(int)body];
+	}
+
+	Quaternion CJoint::getRotation(JointBody body) const
+	{
+		return mRotations[(int)body];
+	}
+
+	void CJoint::setTransform(JointBody body, const Vector3& position, const Quaternion& rotation)
+	{
+		if (mPositions[(int)body] == position && mRotations[(int)body] == rotation)
+			return;
+
+		mPositions[(int)body] = position;
+		mRotations[(int)body] = rotation;
+
+		if(mInternal != nullptr)
+			updateTransform(body);
+	}
+
+	float CJoint::getBreakForce() const
+	{
+		return mBreakForce;
+	}
+
+	void CJoint::setBreakForce(float force)
+	{
+		if (mBreakForce == force)
+			return;
+
+		mBreakForce = force;
+
+		if (mInternal != nullptr)
+			mInternal->setBreakForce(force);
+	}
+
+	float CJoint::getBreakTorque() const
+	{
+		return mBreakTorque;
+	}
+
+	void CJoint::setBreakToque(float torque)
+	{
+		if (mBreakTorque == torque)
+			return;
+
+		mBreakTorque = torque;
+
+		if (mInternal != nullptr)
+			mInternal->setBreakTorque(torque);
+	}
+
+	bool CJoint::getEnableCollision() const
+	{
+		return mEnableCollision;
+	}
+
+	void CJoint::setEnableCollision(bool value)
+	{
+		if (mEnableCollision == value)
+			return;
+
+		mEnableCollision = value;
+
+		if (mInternal != nullptr)
+			mInternal->setEnableCollision(value);
+	}
+
+	void CJoint::onInitialized()
+	{
+
+	}
+
+	void CJoint::onDestroyed()
+	{
+		if (mBodies[0] != nullptr)
+			mBodies[0]->_setJoint(HJoint());
+
+		if (mBodies[1] != nullptr)
+			mBodies[1]->_setJoint(HJoint());
+
+		destroyInternal();
+	}
+
+	void CJoint::onDisabled()
+	{
+		destroyInternal();
+	}
+
+	void CJoint::onEnabled()
+	{
+		restoreInternal();
+	}
+
+	void CJoint::onTransformChanged(TransformChangedFlags flags)
+	{
+		if (!SO()->getActive())
+			return;
+
+		// We're ignoring this during physics update because it would cause problems if the joint itself was moved by physics
+		// Note: This isn't particularily correct because if the joint is being moved by physics but the rigidbodies
+		// themselves are not parented to the joint, the transform will need updating. However I'm leaving it up to the
+		// user to ensure rigidbodies are always parented to the joint in such a case (It's an unlikely situation that
+		// I can't think of an use for - joint transform will almost always be set as an initialization step and not a 
+		// physics response).
+		if (gPhysics()._isUpdateInProgress())
+			return;
+
+		updateTransform(JointBody::A);
+		updateTransform(JointBody::B);
+	}
+
+	void CJoint::restoreInternal()
+	{
+		if (mInternal == nullptr)
+		{
+			mInternal = createInternal();
+
+			mInternal->onJointBreak.connect(std::bind(&CJoint::triggerOnJointBroken, this));
+		}
+
+		// Note: Merge into one call to avoid many virtual function calls
+		Rigidbody* bodies[2];
+
+		if (mBodies[0] != nullptr)
+			bodies[0] = mBodies[0]->_getInternal();
+		else
+			bodies[0] = nullptr;
+
+		if (mBodies[1] != nullptr)
+			bodies[1] = mBodies[1]->_getInternal();
+		else
+			bodies[1] = nullptr;
+
+		mInternal->setBody(JointBody::A, bodies[0]);
+		mInternal->setBody(JointBody::B, bodies[1]);
+		mInternal->setBreakForce(mBreakForce);
+		mInternal->setBreakTorque(mBreakTorque);
+		mInternal->setEnableCollision(mEnableCollision);
+
+		updateTransform(JointBody::A);
+		updateTransform(JointBody::B);
+	}
+
+	void CJoint::destroyInternal()
+	{
+		// This should release the last reference and destroy the internal joint
+		mInternal->_setOwner(PhysicsOwnerType::None, nullptr);
+		mInternal = nullptr;
+	}
+
+	void CJoint::notifyRigidbodyMoved(const HRigidbody& body)
+	{
+		// If physics update is in progress do nothing, as its the joint itself that's probably moving the body
+		if (gPhysics()._isUpdateInProgress())
+			return;
+
+		if (mBodies[0] == body)
+			updateTransform(JointBody::A);
+		else if (mBodies[1] == body)
+			updateTransform(JointBody::B);
+		else
+			assert(false); // Not allowed to happen
+	}
+
+	void CJoint::updateTransform(JointBody body)
+	{
+		Vector3 localPos;
+		Quaternion localRot;
+
+		localPos = mPositions[(int)body];
+		localRot = mRotations[(int)body];
+
+		// Transform to world space of the related body
+		HRigidbody rigidbody = mBodies[(int)body];
+		if (rigidbody != nullptr)
+		{
+			Quaternion worldRot = rigidbody->SO()->getWorldRotation();
+
+			localRot = worldRot * localRot;
+			localPos = worldRot.rotate(localPos) + rigidbody->SO()->getWorldPosition();
+		}
+
+		// Transform to space local to the joint
+		Quaternion invRotation = SO()->getWorldRotation().inverse();
+
+		localPos = invRotation.rotate(localPos - SO()->getWorldPosition());
+		localRot = invRotation * localRot;
+
+		mInternal->setTransform(body, localPos, localRot);
+	}
+	
+	void CJoint::triggerOnJointBroken()
+	{
+		onJointBreak();
+	}
+
+	RTTITypeBase* CJoint::getRTTIStatic()
+	{
+		return CJointRTTI::instance();
+	}
+
+	RTTITypeBase* CJoint::getRTTI() const
+	{
+		return CJoint::getRTTIStatic();
+	}
 }

+ 36 - 0
Source/BansheeEditor/Include/BsGizmoManager.h

@@ -78,6 +78,18 @@ namespace BansheeEngine
 		 */
 		void drawSphere(const Vector3& position, float radius);
 
+		/**
+		 * Draws a solid cone.
+		 *
+		 * @param[in]	base		Position of the center of the base of the cone.
+		 * @param[in]	normal		Orientation of the cone, pointing from center base to the tip of the cone.
+		 * @param[in]	height		Height of the cone (along the normal).
+		 * @param[in]	radius		Radius of the base of the cone.
+		 * @param[in]	scale		Scale applied to cone's disc width & height. Allows you to create elliptical cones.
+		 */
+		void drawCone(const Vector3& base, const Vector3& normal, float height, float radius, 
+			const Vector2& scale = Vector2::ONE);
+
 		/**
 		 * Draws a wireframe axis aligned cuboid.
 		 *
@@ -104,6 +116,18 @@ namespace BansheeEngine
 		 */
 		void drawWireCapsule(const Vector3& position, float height, float radius);
 
+		/**
+		 * Draws a wireframe cone.
+		 *
+		 * @param[in]	base		Position of the center of the base of the cone.
+		 * @param[in]	normal		Orientation of the cone, pointing from center base to the tip of the cone.
+		 * @param[in]	height		Height of the cone (along the normal).
+		 * @param[in]	radius		Radius of the base of the cone.
+		 * @param[in]	scale		Scale applied to cone's disc width & height. Allows you to create elliptical cones.
+		 */
+		void drawWireCone(const Vector3& base, const Vector3& normal, float height, float radius, 
+			const Vector2& scale = Vector2::ONE);
+
 		/**
 		 * Draws a line between two points.
 		 *
@@ -254,6 +278,16 @@ namespace BansheeEngine
 			float radius;
 		};
 
+		/**	Data required for rendering a cone gizmo. */
+		struct ConeData : CommonData
+		{
+			Vector3 base;
+			Vector3 normal;
+			float radius;
+			float height;
+			Vector2 scale;
+		};
+
 		/**	Data required for rendering a line gizmo. */
 		struct LineData : CommonData
 		{
@@ -402,6 +436,8 @@ namespace BansheeEngine
 		Vector<CubeData> mWireCubeData;
 		Vector<SphereData> mSolidSphereData;
 		Vector<SphereData> mWireSphereData;
+		Vector<ConeData> mSolidConeData;
+		Vector<ConeData> mWireConeData;
 		Vector<LineData> mLineData;
 		Vector<LineListData> mLineListData;
 		Vector<WireDiscData> mWireDiscData;

+ 60 - 0
Source/BansheeEditor/Source/BsGizmoManager.cpp

@@ -168,6 +168,23 @@ namespace BansheeEngine
 		mIdxToSceneObjectMap[sphereData.idx] = mActiveSO;
 	}
 
+	void GizmoManager::drawCone(const Vector3& base, const Vector3& normal, float height, float radius, const Vector2& scale)
+	{
+		mSolidConeData.push_back(ConeData());
+		ConeData& sphereData = mSolidConeData.back();
+
+		sphereData.idx = mCurrentIdx++;
+		sphereData.base = base;
+		sphereData.radius = radius;
+		sphereData.color = mColor;
+		sphereData.transform = mTransform;
+		sphereData.sceneObject = mActiveSO;
+		sphereData.pickable = mPickable;
+
+		mDrawHelper->cone(base, normal, height, radius, scale);
+		mIdxToSceneObjectMap[sphereData.idx] = mActiveSO;
+	}
+
 	void GizmoManager::drawWireCube(const Vector3& position, const Vector3& extents)
 	{
 		mWireCubeData.push_back(CubeData());
@@ -238,6 +255,23 @@ namespace BansheeEngine
 		drawWireDisc(botHemisphere, Vector3::UNIT_Y, radius);
 	}
 
+	void GizmoManager::drawWireCone(const Vector3& base, const Vector3& normal, float height, float radius, const Vector2& scale)
+	{
+		mWireConeData.push_back(ConeData());
+		ConeData& sphereData = mWireConeData.back();
+
+		sphereData.idx = mCurrentIdx++;
+		sphereData.base = base;
+		sphereData.radius = radius;
+		sphereData.color = mColor;
+		sphereData.transform = mTransform;
+		sphereData.sceneObject = mActiveSO;
+		sphereData.pickable = mPickable;
+
+		mDrawHelper->cone(base, normal, height, radius, scale);
+		mIdxToSceneObjectMap[sphereData.idx] = mActiveSO;
+	}
+
 	void GizmoManager::drawLine(const Vector3& start, const Vector3& end)
 	{
 		mLineData.push_back(LineData());
@@ -488,6 +522,30 @@ namespace BansheeEngine
 			mPickingDrawHelper->wireSphere(sphereDataEntry.position, sphereDataEntry.radius);
 		}
 
+		for (auto& coneDataEntry : mSolidConeData)
+		{
+			if (!coneDataEntry.pickable)
+				continue;
+
+			mPickingDrawHelper->setColor(idxToColorCallback(coneDataEntry.idx));
+			mPickingDrawHelper->setTransform(coneDataEntry.transform);
+
+			mPickingDrawHelper->cone(coneDataEntry.base, coneDataEntry.normal, coneDataEntry.radius, coneDataEntry.radius, 
+				coneDataEntry.scale);
+		}
+
+		for (auto& coneDataEntry : mWireConeData)
+		{
+			if (!coneDataEntry.pickable)
+				continue;
+
+			mPickingDrawHelper->setColor(idxToColorCallback(coneDataEntry.idx));
+			mPickingDrawHelper->setTransform(coneDataEntry.transform);
+
+			mPickingDrawHelper->wireCone(coneDataEntry.base, coneDataEntry.normal, coneDataEntry.radius, coneDataEntry.radius,
+				coneDataEntry.scale);
+		}
+
 		for (auto& lineDataEntry : mLineData)
 		{
 			if (!lineDataEntry.pickable)
@@ -622,6 +680,8 @@ namespace BansheeEngine
 		mWireCubeData.clear();
 		mSolidSphereData.clear();
 		mWireSphereData.clear();
+		mSolidConeData.clear();
+		mWireConeData.clear();
 		mLineData.clear();
 		mLineListData.clear();
 		mWireDiscData.clear();

+ 9 - 1
Source/BansheeEngine/Include/BsDrawHelper.h

@@ -5,6 +5,7 @@
 #include "BsPrerequisites.h"
 #include "BsMatrix4.h"
 #include "BsVector3.h"
+#include "BsVector2.h"
 #include "BsColor.h"
 #include "BsRect3.h"
 
@@ -77,7 +78,12 @@ namespace BansheeEngine
 		void frustum(const Vector3& position, float aspect, Degree FOV, float near, float far);
 
 		/**	Records a solid cone with the specified properties in the internal draw queue. */
-		void cone(const Vector3& base, const Vector3& normal, float height, float radius, UINT32 quality = 10);
+		void cone(const Vector3& base, const Vector3& normal, float height, float radius, 
+			const Vector2& scale = Vector2::ONE, UINT32 quality = 10);
+
+		/**	Records a wire cone with the specified properties in the internal draw queue. */
+		void wireCone(const Vector3& base, const Vector3& normal, float height, float radius,
+			const Vector2& scale = Vector2::ONE, UINT32 quality = 10);
 
 		/**	Records a solid disc with the specified properties in the internal draw queue. */
 		void disc(const Vector3& position, const Vector3& normal, float radius, UINT32 quality = 10);
@@ -187,6 +193,7 @@ namespace BansheeEngine
 			Vector3 normal;
 			float height;
 			float radius;
+			Vector2 scale;
 			UINT32 quality;
 		};
 
@@ -237,6 +244,7 @@ namespace BansheeEngine
 		Vector<Rect3Data> mRect3Data;
 		Vector<FrustumData> mFrustumData;
 		Vector<ConeData> mConeData;
+		Vector<ConeData> mWireConeData;
 		Vector<DiscData> mDiscData;
 		Vector<DiscData> mWireDiscData;
 		Vector<ArcData> mArcData;

+ 727 - 671
Source/BansheeEngine/Include/BsShapeMeshes3D.h

@@ -1,672 +1,728 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-#pragma once
-
-#include "BsPrerequisites.h"
-#include "BsColor.h"
-#include "BsAABox.h"
-#include "BsRect3.h"
-
-namespace BansheeEngine
-{
-	/** @addtogroup Utility-Engine
-	 *  @{
-	 */
-
-	/**	Helper class for easily creating common 3D shapes. */
-	class BS_EXPORT ShapeMeshes3D
-	{
-	public:
-		/**
-		 * Fills the mesh data with vertices representing an outline of axis aligned box.
-		 *
-		 * @param[in]		aabox			Axis aligned box to create the mesh data for
-		 * @param[in, out]	meshData		Mesh data that will be populated.
-		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 * 							
-		 * @note	
-		 * Provided MeshData must have some specific elements at least:
-		 *  Vector3 VES_POSITION
-		 *  32bit index buffer
-		 *  Enough space for 8 vertices and 24 indices
-		 * @note
-		 * Primitives are output in the form of a line list.
-		 */
-		static void wireAABox(const AABox& box, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
-
-		/**
-		 * Fills the mesh data with vertices representing a solid axis aligned box.
-		 *
-		 * @param[in]		aabox			Axis aligned box to create the mesh data for
-		 * @param[in, out]	meshData		Mesh data that will be populated.
-		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 * 							
-		 * @note	
-		 * Provided MeshData must have some specific elements at least:
-		 *  Vector3 VES_POSITION
-		 *	Vector3 VES_NORMAL
-		 * 	32bit index buffer
-		 * 	Enough space for 24 vertices and 36 indices
-		 * @note
-		 * Primitives are output in the form of a triangle list.
-		 */
-		static void solidAABox(const AABox& box, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
-
-		/**
-		 * Fills the mesh data with vertices representing an outline of a sphere.
-		 *
-		 * @param[in]		sphere			Sphere to get the mesh data for
-		 * @param[in, out]	meshData		Mesh data that will be populated.
-		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 * @param[in]		quality			Represents the level of tessellation the sphere will have. Higher level means 
-		 *									higher quality but also more vertices and primitives.
-		 *
-		 * @note	
-		 * Provided MeshData must have some specific elements at least:
-		 *  Vector3 VES_POSITION
-		 *  32bit index buffer
-		 *  Enough space for 3 * ((quality + 1) * 5) vertices 
-		 *	Enough space for 6 * ((quality + 1) * 5 - 1) indices
-		 * @note
-		 * Primitives are output in the form of a line list.
-		 */
-		static void wireSphere(const Sphere& sphere, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, 
-			UINT32 quality = 10);
-
-		/**
-		 * Fills the mesh data with vertices representing a sphere.
-		 *
-		 * @param[in]		sphere			Sphere to get the mesh data for
-		 * @param[in, out]	meshData		Mesh data that will be populated.
-		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 * @param[in]		quality			Represents the level of tessellation the sphere will have. Higher level means 
-		 *									higher quality but also more vertices and primitives.
-		 *
-		 * @note	
-		 * Provided MeshData must have some specific elements at least:
-		 *  Vector3 VES_POSITION
-		 *	Vector3 VES_NORMAL
-		 * 	32bit index buffer
-		 * 	Enough space for 20 * (4 * (3 ^ quality)) vertices 
-		 *	Enough space for 20 * (4 * (3 ^ quality)) indices
-		 * @note
-		 * Primitives are output in the form of a triangle list.
-		 */
-		static void solidSphere(const Sphere& sphere, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, 
-			UINT32 quality = 1);
-
-		/**
-		 * Fills the mesh data with vertices representing an outline of an arc.
-		 *
-		 * @param[in]		center			Center of the arc to generate geometry for.
-		 * @param[in]		radius			Radius of the arc to generate geometry for.
-		 * @param[in]		normal			Normal around which the arc is generated. Arc geometry will be perpendicular
-		 *									to the normal.
-		 * @param[in]		startAngle		Angle at which the arc starts.
-		 * @param[in]		amountAngle		Angle that the arc spans.
-		 * @param[in, out]	meshData		Mesh data that will be populated.
-		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 * @param[in]		quality			Represents the level of tessellation the arc will have. Higher level means
-		 *									higher quality but also more vertices and primitives.
-		 *
-		 * @note	
-		 * Provided MeshData must have some specific elements at least:
-		 *  Vector3 VES_POSITION
-		 *  32bit index buffer
-		 *  Enough space for ((quality + 1) * 5) vertices 
-		 *	Enough space for (((quality + 1) * 5 - 1) * 2) indices
-		 * @note
-		 * Primitives are output in the form of a line list.
-		 */
-		static void wireArc(const Vector3& center, float radius, const Vector3& normal, Degree startAngle, Degree amountAngle,
-			const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality = 10);
-
-		/**
-		 * Fills the mesh data with vertices representing a solid double-sided arc.
-		 *
-		 * @param[in]		center			Center of the arc to generate geometry for.
-		 * @param[in]		radius			Radius of the arc to generate geometry for.
-		 * @param[in]		normal			Normal around which the arc is generated. Arc geometry will be perpendicular to
-		 *									the normal.
-		 * @param[in]		startAngle		Angle at which the arc starts.
-		 * @param[in]		amountAngle		Angle that the arc spans.
-		 * @param[in, out]	meshData		Mesh data that will be populated.
-		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 * @param[in]		quality			Represents the level of tessellation the arc will have. Higher level means higher 
-		 *									quality but also more vertices and primitives.
-		 *
-		 * @note	
-		 * Provided MeshData must have some specific elements at least:
-		 *  Vector3 VES_POSITION
-		 *	Vector3 VES_NORMAL
-		 * 	32bit index buffer
-		 * 	Enough space for ((quality + 1) * 5 + 1) * 2 vertices 
-		 *	Enough space for (((quality + 1) * 5 - 1) * 6) indices
-		 * @note
-		 * Primitives are output in the form of a triangle list.
-		 */
-		static void solidArc(const Vector3& center, float radius, const Vector3& normal, Degree startAngle, Degree amountAngle,
-			const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality = 10);
-
-		/**
-		 * Fills the mesh data with vertices representing an outline of a disc.
-		 *
-		 * @param[in]		center			Center of the disc to generate geometry for.
-		 * @param[in]		radius			Radius of the disc to generate geometry for.
-		 * @param[in]		normal			Normal around which the disc is generated. Disc geometry will be perpendicular
-		 *									to the normal.
-		 * @param[in, out]	meshData		Mesh data that will be populated.
-		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 * @param[in]		quality			Represents the level of tessellation the disc will have. Higher level means
-		 *									higher quality but also more vertices and primitives.
-		 *
-		 * @note	
-		 * Provided MeshData must have some specific elements at least:
-		 * 	Vector3 VES_POSITION
-		 * 	32bit index buffer
-		 * 	Enough space for ((quality + 1) * 5) vertices 
-		 *	Enough space for (((quality + 1) * 5 - 1) * 2) indices
-		 * @note
-		 * Primitives are output in the form of a line list.
-		 */
-		static void wireDisc(const Vector3& center, float radius, const Vector3& normal, const MeshDataPtr& meshData,
-			UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality = 10);
-
-		/**
-		 * Fills the mesh data with vertices representing a solid double-sided disc.
-		 *
-		 * @param[in]		center			Center of the disc to generate geometry for.
-		 * @param[in]		radius			Radius of the disc to generate geometry for.
-		 * @param[in]		normal			Normal around which the disc is generated. Disc geometry will be perpendicular 
-		 *									to the normal.
-		 * @param[in, out]	meshData		Mesh data that will be populated.
-		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 * @param[in]		quality			Represents the level of tessellation the disc will have. Higher level means higher
-		 *									quality but also more vertices and primitives.
-		 *
-		 * @note	
-		 * Provided MeshData must have some specific elements at least:
-		 *  Vector3 VES_POSITION
-		 *	Vector3 VES_NORMAL
-		 * 	32bit index buffer
-		 * 	Enough space for ((quality + 1) * 5 + 1) * 2 vertices 
-		 *	Enough space for (((quality + 1) * 5 - 1) * 6) indices
-		 * @note
-		 * Primitives are output in the form of a triangle list.
-		 */
-		static void solidDisc(const Vector3& center, float radius, const Vector3& normal, const MeshDataPtr& meshData,
-			UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality = 10);
-
-		/**
-		 * Fills the mesh data with vertices representing an outline of an camera frustum. Frustum will be facing -z and be
-		 * positioned at world origin.
-		 *
-		 * @param[in]		position		Starting point for the frustum.
-		 * @param[in]		aspect			Aspect ratio (width / height).
-		 * @param[in]		FOV				Horizontal field of view angle.
-		 * @param[in]		near			Distance to near clipping plane.
-		 * @param[in]		far				Distance to far clipping plane.
-		 * @param[in, out]	meshData		Mesh data that will be populated.
-		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 * 							
-		 * @note	
-		 * Provided MeshData must have some specific elements at least:
-		 *  Vector3 VES_POSITION
-		 *  32bit index buffer
-		 *  Enough space for 8 vertices and 24 indices
-		 * @note
-		 * Primitives are output in the form of a line list.
-		 */
-		static void wireFrustum(const Vector3& position, float aspect, Degree FOV, float near, float far,
-			const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
-
-		/**
-		 * Fills the mesh data with vertices representing a solid cone.
-		 *
-		 * @param[in]		base			World position of the cone base.
-		 * @param[in]		normal			Direction of the pointed part of the cone.
-		 * @param[in]		height			Cone height (distance from base to the top).
-		 * @param[in]		radius			Cone radius (distance from base center to outer edge).
-		 * @param[in, out]	meshData		Mesh data that will be populated.
-		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 * @param[in]		quality			Represents the level of tessellation the cone will have. Higher level means 
-		 *									higher quality but also more vertices and primitives.
-		 *
-		 * @note	
-		 * Provided MeshData must have some specific elements at least:
-		 *  Vector3 VES_POSITION
-		 *	Vector3 VES_NORMAL
-		 * 	32bit index buffer
-		 * 	Enough space for ((quality + 1) * 4 + 1) * 2 vertices 
-		 *	Enough space for (((quality + 1) * 4 - 1) * 6) indices
-		 * @note
-		 * Primitives are output in the form of a triangle list.
-		 */
-		static void solidCone(const Vector3& base, const Vector3& normal, float height, float radius,
-			const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality = 10);
-
-		/**
-		 * Fills the mesh data with vertices representing a quad (4 triangles, two sided).
-		 *
-		 * @param[in]		area			Area in which to draw the quad.
-		 * @param[in, out]	meshData		Mesh data that will be populated.
-		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 * 							
-		 * @note	
-		 * Provided MeshData must have some specific elements at least:
-		 *  Vector3 VES_POSITION
-		 *	Vector3 VES_NORMAL
-		 * 	32bit index buffer
-		 * 	Enough space for 8 vertices and 12 indices
-		 * @note
-		 * Primitives are output in the form of a triangle list.
-		 */
-		static void solidQuad(const Rect3& area, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
-
-		/**
-		 * Fills the mesh data with vertices representing a per-pixel line.
-		 *
-		 * @param[in]		a				Start point of the line.
-		 * @param[in]		b				End point of the line.
-		 * @param[in, out]	meshData	Mesh data that will be populated.
-		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 * 							
-		 * @note	
-		 * Provided MeshData must have some specific elements at least:
-		 *  Vector3	  VES_POSITION
-		 *  32bit index buffer
-		 *  Enough space for 2 vertices and 2 indices
-		 * @note
-		 * Primitives are output in the form of a line list.
-		 */
-		static void pixelLine(const Vector3& a, const Vector3& b, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
-
-		/**
-		 * Fills the mesh data with vertices representing an anti-aliased line of specific width. Antialiasing is done 
-		 * using alpha blending.
-		 *
-		 * @param[in]		a				Start point of the line.
-		 * @param[in]		b				End point of the line.
-		 * @param[in]		up				Up direction to which the line will run perpendicular to.
-		 * @param[in]		width			Width of the line.
-		 * @param[in]		borderWidth		Width of the anti-aliased border.
-		 * @param[in]		color			Color of the line.
-		 * @param[in, out]	meshData	Mesh data that will be populated by this method.
-		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 * 							
-		 * @note	
-		 * Provided MeshData must have some specific elements at least:
-		 *  Vector3 VES_POSITION
-		 *  UINT32  VES_COLOR
-		 *  32bit index buffer
-		 *	Enough space for 8 vertices and 30 indices
-		 * @note
-		 * Primitives are output in the form of a triangle list.
-		 */
-		static void antialiasedLine(const Vector3& a, const Vector3& b, const Vector3& up, float width, float borderWidth, const Color& color,
-			const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
-
-		/**
-		 * Fills the mesh data with vertices representing per-pixel lines.
-		 *
-		 * @param[in]		linePoints		A list of start and end points for the lines. Must be a multiple of 2.
-		 * @param[in, out]	meshData		Mesh data that will be populated.
-		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 * 							
-		 * @note	
-		 * Provided MeshData must have some specific elements at least:
-		 *  Vector3  VES_POSITION
-		 *  32bit index buffer
-		 *  Enough space for (numLines * 2) vertices and (numLines * 2) indices
-		 * @note
-		 * Primitives are output in the form of a line list.
-		 */
-		static void pixelLineList(const Vector<Vector3>& linePoints, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
-
-		/**
-		 * Fills the mesh data with vertices representing anti-aliased lines of specific width. Antialiasing is done using
-		 * alpha blending.
-		 *
-		 * @param[in]		linePoints		A list of start and end points for the lines. Must be a multiple of 2.
-		 * @param[in]		up				Up direction to which the line will run perpendicular to.
-		 * @param[in]		width			Width of the line.
-		 * @param[in]		borderWidth		Width of the anti-aliased border.
-		 * @param[in]		color			Color of the line.
-		 * @param[in, out]	meshData		Mesh data that will be populated by this method.
-		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 * 							
-		 * @note	
-		 * Provided MeshData must have some specific elements at least:
-		 *  Vector3 VES_POSITION
-		 *  UINT32  VES_COLOR
-		 *  32bit index buffer
-		 *	Enough space for (numLines * 8) vertices and (numLines * 30) indices
-		 * @note
-		 * Primitives are output in the form of a triangle list.
-		 */
-		static void antialiasedLineList(const Vector<Vector3>& linePoints, const Vector3& up, float width, float borderWidth,
-			const Color& color, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
-
-		/**
-		 * Fills the provided buffers with position and index data representing an outline of an axis aligned box. Use 
-		 * getNumElementsWireAABox() to determine the required sizes of the output buffers.
-		 *
-		 * @param[in]	box				Box to create geometry for.
-		 * @param[out]	outVertices		Pre-allocated output buffer that will store the vertex position data.
-		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]	vertexStride	Size of a single vertex, in bytes.
-		 * @param[out]	outIndices		Pre-allocated output buffer that will store the index data. Indices are 32bit.
-		 * @param[in]	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 */
-		static void wireAABox(const AABox& box, UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride,
-			UINT32* outIndices, UINT32 indexOffset);
-
-		/**
-		 * Fills the provided buffers with position and index data representing a solid axis aligned box. Use 
-		 * getNumElementsAABox() to determine the required sizes of the output buffers.
-		 *
-		 * @param[in]	box				Box to create geometry for.
-		 * @param[out]	outVertices		Pre-allocated output buffer that will store the vertex position data.
-		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]	vertexStride	Size of a single vertex, in bytes. (Same for both position and normal buffer)
-		 * @param[out]	outIndices		Pre-allocated output buffer that will store the index data. Indices are 32bit.
-		 * @param[in]	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 */
-		static void solidAABox(const AABox& box, UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride,
-			UINT32* outIndices, UINT32 indexOffset);
-
-		/**
-		 * Fills the provided buffers with position and index data representing a sphere. Use getNumElementsSphere() to
-		 * determine the required sizes of the output buffers.
-		 *
-		 * @param[in]	sphere			Sphere to create geometry for.
-		 * @param[out]	outVertices		Pre-allocated output buffer that will store the vertex position data.
-		 * @param[out]	outNormals		Pre-allocated output buffer that will store the vertex normal data. Can be null if
-		 *								normals aren't needed.
-		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]	vertexStride	Size of a single vertex, in bytes. (Same for both position and normal buffer)
-		 * @param[out]	outIndices		Pre-allocated output buffer that will store the index data. Indices are 32bit.
-		 * @param[in]	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 * @param[in]	quality			Represents the level of tessellation the sphere will have. Higher level means higher
-		 *								quality but also more vertices and primitives.
-		 */
-		static void solidSphere(const Sphere& sphere, UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride,
-			UINT32* outIndices, UINT32 indexOffset, UINT32 quality);
-
-		/**
-		 * Fills the provided buffers with position and index data representing an outline of an arc. Use
-		 * getNumElementWiresArc() to determine the required sizes of the output buffers.
-		 *
-		 * @param[in]	center			Center of the arc to generate geometry for.
-		 * @param[in]	radius			Radius of the arc to generate geometry for.
-		 * @param[in]	normal			Normal around which the arc is generated. Arc geometry will be perpendicular to the
-		 *								normal.
-		 * @param[in]	startAngle		Angle at which the arc starts.
-		 * @param[in]	amountAngle		Angle that the arc spans.
-		 * @param[out]	outVertices		Pre-allocated output buffer that will store the vertex position data.
-		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]	vertexStride	Size of a single vertex, in bytes.
-		 * @param[out]	outIndices		Pre-allocated output buffer that will store the index data. Indices are 32bit.
-		 * @param[in]	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 * @param[in]	quality			Represents the level of tessellation the arc will have. Higher level means higher
-		 *								quality but also more vertices and primitives.
-		 */
-		static void wireArc(const Vector3& center, float radius, const Vector3& normal, Degree startAngle, Degree amountAngle,
-			UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset, UINT32 quality);
-
-		/**
-		 * Fills the provided buffers with position and index data representing a solid arc. Use getNumElementsArc() to
-		 * determine the required sizes of the output buffers.
-		 *
-		 * @param[in]	center			Center of the arc to generate geometry for.
-		 * @param[in]	radius			Radius of the arc to generate geometry for.
-		 * @param[in]	normal			Normal around which the arc is generated. Arc geometry will be perpendicular to the
-		 *								normal.
-		 * @param[in]	startAngle		Angle at which the arc starts.
-		 * @param[in]	amountAngle		Angle that the arc spans.
-		 * @param[out]	outVertices		Pre-allocated output buffer that will store the vertex position data.
-		 * @param[out]	outNormals		Pre-allocated output buffer that will store the vertex normal data.
-		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]	vertexStride	Size of a single vertex, in bytes. (Same for both position and normal buffer)
-		 * @param[out]	outIndices		Pre-allocated output buffer that will store the index data. Indices are 32bit.
-		 * @param[in]	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 * @param[in]	quality			Represents the level of tessellation the arc will have. Higher level means higher
-		 *								quality but also more vertices and primitives.
-		 */
-		static void solidArc(const Vector3& center, float radius, const Vector3& normal, Degree startAngle, Degree amountAngle,
-			UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset, UINT32 quality);
-
-		/**
-		 * Fills the provided buffers with position and index data representing an outline of a camera frustum. Use
-		 * getNumElementsFrustum() to determine the required sizes of the output buffers.
-		 *
-		 * @param[in]	position		Starting point for the frustum.
-		 * @param[in]	aspect			Aspect ratio (width / height).
-		 * @param[in]	FOV				Horizontal field of view angle.
-		 * @param[in]	near			Distance to near clipping plane.
-		 * @param[in]	far				Distance to far clipping plane.
-		 * @param[out]	outVertices		Pre-allocated output buffer that will store the vertex position data.
-		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]	vertexStride	Size of a single vertex, in bytes.
-		 * @param[out]	outIndices		Pre-allocated output buffer that will store the index data. Indices are 32bit.
-		 * @param[in]	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 */
-		static void wireFrustum(const Vector3& position, float aspect, Degree FOV, float near, float far,
-			UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
-
-		/**
-		 * Fills the provided buffers with position and index data representing a solid cone. Use getNumElementsCone() to
-		 * determine the required sizes of the output buffers.
-		 *
-		 * @param[in]	base			World position of the cone base.
-		 * @param[in]	normal			Direction of the pointed part of the cone.
-		 * @param[in]	height			Cone height (distance from base to the top).
-		 * @param[in]	radius			Cone radius (distance from base center to outer edge).
-		 * @param[out]	outVertices		Pre-allocated output buffer that will store the vertex position data.
-		 * @param[out]	outNormals		Pre-allocated output buffer that will store the vertex normal data. Can be null if
-		 *								normals aren't needed.
-		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]	vertexStride	Size of a single vertex, in bytes. (Same for both position and normal buffer)
-		 * @param[out]	outIndices		Pre-allocated output buffer that will store the index data. Indices are 32bit.
-		 * @param[in]	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 * @param[in]	quality			Represents the level of tessellation the cone will have. Higher level means higher
-		 *								quality but also more vertices and primitives.
-		 */
-		static void solidCone(const Vector3& base, const Vector3& normal, float height, float radius,
-			UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset, UINT32 quality);
-
-		/**
-		 * Fills the provided buffers with position and index data representing a solid quad. Use getNumElementsCone() to
-		 * determine the required sizes of the output buffers.
-		 *
-		 * @param[in]	area			Area covered by the quad.
-		 * @param[out]	outVertices		Pre-allocated output buffer that will store the vertex position data.
-		 * @param[out]	outNormals		Pre-allocated output buffer that will store the vertex normal data.
-		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]	vertexStride	Size of a single vertex, in bytes. (Same for both position and normal buffer)
-		 * @param[out]	outIndices		Pre-allocated output buffer that will store the index data. Indices are 32bit.
-		 * @param[in]	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 */
-		static void solidQuad(const Rect3& area, UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
-
-		/**	Calculates number of vertices and indices required for geometry of a solid axis aligned box. */
-		static void getNumElementsAABox(UINT32& numVertices, UINT32& numIndices);
-
-		/**	Calculates number of vertices and indices required for geometry of a wireframe axis aligned box. */
-		static void getNumElementsWireAABox(UINT32& numVertices, UINT32& numIndices);
-
-		/**	Calculates number of vertices and indices required for geometry of a solid sphere of the specified quality. */
-		static void getNumElementsSphere(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
-
-		/**	Calculates number of vertices and indices required for geometry of a wire sphere of the specified quality. */
-		static void getNumElementsWireSphere(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
-
-		/**	Calculates number of vertices and indices required for geometry of a solid arc of the specified quality. */
-		static void getNumElementsArc(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
-
-		/**	Calculates number of vertices and indices required for geometry of a wire arc of the specified quality. */
-		static void getNumElementsWireArc(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
-
-		/**	Calculates number of vertices and indices required for geometry of a solid desc	of the specified quality. */
-		static void getNumElementsDisc(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
-
-		/**	Calculates number of vertices and indices required for geometry of a wire disc of the specified quality. */
-		static void getNumElementsWireDisc(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
-
-		/**	Calculates number of vertices and indices required for geometry of a cone of the specified quality. */
-		static void getNumElementsCone(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
-
-		/**	Calculates number of vertices and indices required for geometry of a frustum. */
-		static void getNumElementsFrustum(UINT32& numVertices, UINT32& numIndices);
-
-		/**	Calculates number of vertices and indices required for geometry of a quadrirateral. */
-		static void getNumElementsQuad(UINT32& numVertices, UINT32& numIndices);
-
-		static const UINT32 NUM_VERTICES_AA_LINE;
-		static const UINT32 NUM_INDICES_AA_LINE;
-
-	protected:
-		/**
-		 * Fills the provided buffers with vertices representing a per-pixel line.
-		 *
-		 * @param[in]	a				Start point of the line.
-		 * @param[in]	b				End point of the line.
-		 * @param[out]	outVertices		Output buffer that will store the vertex position data.
-		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
-		 * @param[out]	outIndices		Output buffer that will store the index data. Indices are 32bit.
-		 * @param[in]	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 */
-		static void pixelLine(const Vector3& a, const Vector3& b, UINT8* outVertices,
-			UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
-
-		/**
-		 * Fills the provided buffers with vertices representing an antialiased line with a custom width.
-		 *
-		 * @param[in]	a				Start point of the line.
-		 * @param[in]	b				End point of the line.
-		 * @param[in]	up				Up direction to which the line will run perpendicular to.
-		 * @param[in]	width			Width of the line.
-		 * @param[in]	borderWidth		Width of the anti-aliased border.
-		 * @param[in]	color			Color of the line.
-		 * @param[out]	outVertices		Output buffer that will store the vertex position data.
-		 * @param[out]	outColors		Output buffer that will store the vertex color data.
-		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
-		 * @param[out]	outIndices		Output buffer that will store the index data. Indices are 32bit.
-		 * @param[in]	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 */
-		static void antialiasedLine(const Vector3& a, const Vector3& b, const Vector3& up, float width, float borderWidth, 
-			const Color& color, UINT8* outVertices, UINT8* outColors, UINT32 vertexOffset, UINT32 vertexStride, 
-			UINT32* outIndices, UINT32 indexOffset);
-
-		/**
-		 * Fills the provided buffers with position data and indices representing an inner area of a polygon (basically a
-		 * normal non-antialiased polygon).
-		 *
-		 * @param[in]	points			Points defining the polygon. First point is assumed to be the start and end point.
-		 * @param[out]	outVertices		Output buffer that will store the vertex position data.
-		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
-		 * @param[out]	outIndices		Output buffer that will store the index data. Indices are 32bit.
-		 * @param[in]	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 */
-		static void pixelSolidPolygon(const Vector<Vector3>& points, UINT8* outVertices,
-			UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
-
-		/**
-		 * Fills the provided buffers with vertices representing a pixel-wide polygon border.
-		 *
-		 * @param[in]	points			Points defining the polygon. First point is assumed to be the start and end point.
-		 * @param[out]	outVertices		Output buffer that will store the vertex position data.
-		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
-		 * @param[out]	outIndices		Output buffer that will store the index data. Indices are 32bit.
-		 * @param[in]	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 */
-		static void pixelWirePolygon(const Vector<Vector3>& points, UINT8* outVertices,
-			UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
-
-		/**
-		 * Fills the provided buffers with vertices representing an antialiased polygon.
-		 *
-		 * @param[in]	points			Points defining the polygon. First point is assumed to be the start and end point.
-		 * @param[in]	up				Up direction to which the polygon will run perpendicular to.
-		 * @param[in]	borderWidth		Width of the anti-aliased border.
-		 * @param[in]	color			Color of the polygon.
-		 * @param[out]	outVertices		Output buffer that will store the vertex position data.
-		 * @param[out]	outColors		Output buffer that will store the vertex color data.
-		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
-		 * @param[out]	outIndices		Output buffer that will store the index data. Indices are 32bit.
-		 * @param[in]	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
-		 */
-		static void antialiasedPolygon(const Vector<Vector3>& points, const Vector3& up, float borderWidth, const Color& color, UINT8* outVertices, UINT8* outColors,
-			UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
-
-	private:
-		/**
-		 * Calculates the center of the provided vertices.
-		 * 
-		 * @param[in]	vertices		Buffer containing vertices. Vertices must be of three dimensions at least.
-		 * @param[in]	numVertices		Number of vertices to calculate the center for.
-		 * @param[in]	vertexStride	Number of bytes between two vertices in the buffer.
-		 * @return					Center point of the vertices.
-		 */
-		static Vector3 calcCenter(UINT8* vertices, UINT32 numVertices, UINT32 vertexStride);
-
-		/**
-		 * Subdivides the provided triangle so it approximates a curved surface of a sphere.
-		 *
-		 * @param[in]	center			Center of the sphere to approximate.
-		 * @param[in]	radius			Radius of the sphere to approximate.
-		 * @param[in]	numLevels		Number of times to subdivide the triangle. Higher number means better approximation.
-		 * @param[in]	a				First corner of the triangle. Must be normalized.
-		 * @param[in]	b				Second corner of the triangle. Must be normalized.
-		 * @param[in]	c				Third corner of the triangle. Must be normalized.
-		 * @param[out]	outVertices		Output buffer that will store the vertex position data.
-		 * @param[out]	outNormals		Output buffer that will store the vertex normal data.
-		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
-		 * @return						Number of vertices generated (3 * (4 ^ numLevels)).
-		 */
-		static UINT32 subdivideTriangleOnSphere(const Vector3& center, float radius, UINT32 numLevels,
-			const Vector3& a, const Vector3& b, const Vector3& c,
-			UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride);
-
-		/**
-		 * Generates vertices that are part of an arc approximation.
-		 *
-		 * @param[in]	center			Determines world position of the arc.
-		 * @param[in]	up				Determines rotation of the arc. Arc vertices will be perpendicular to this 
-		 *								direction.
-		 * @param[in]	radius			Distance of arc vertices from the center.
-		 * @param[in]	startAngle		Angle in degrees to start the arc at.
-		 * @param[in]	angleAmount		Angle in degrees to extend the arc from the start angle.
-		 * @param[in]	numVertices		Number of vertices to generate for the arc. Higher number means better arc 
-		 *								approximation. Must be 2 or higher.
-		 * @param[out]	outVertices		Output buffer that will store the vertex position data.
-		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
-		 * @param[in]	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
-		 */
-		static void generateArcVertices(const Vector3& center, const Vector3& up, float radius, Degree startAngle, 
-			Degree angleAmount, UINT32 numVertices, UINT8* outvertices, UINT32 vertexOffset, UINT32 vertexStride);
-	};
-
-	/** @} */
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsPrerequisites.h"
+#include "BsColor.h"
+#include "BsAABox.h"
+#include "BsRect3.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Utility-Engine
+	 *  @{
+	 */
+
+	/**	Helper class for easily creating common 3D shapes. */
+	class BS_EXPORT ShapeMeshes3D
+	{
+	public:
+		/**
+		 * Fills the mesh data with vertices representing an outline of axis aligned box.
+		 *
+		 * @param[in]		aabox			Axis aligned box to create the mesh data for
+		 * @param[in, out]	meshData		Mesh data that will be populated.
+		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * 							
+		 * @note	
+		 * Provided MeshData must have some specific elements at least:
+		 *  Vector3 VES_POSITION
+		 *  32bit index buffer
+		 *  Enough space for 8 vertices and 24 indices
+		 * @note
+		 * Primitives are output in the form of a line list.
+		 */
+		static void wireAABox(const AABox& box, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
+
+		/**
+		 * Fills the mesh data with vertices representing a solid axis aligned box.
+		 *
+		 * @param[in]		aabox			Axis aligned box to create the mesh data for
+		 * @param[in, out]	meshData		Mesh data that will be populated.
+		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * 							
+		 * @note	
+		 * Provided MeshData must have some specific elements at least:
+		 *  Vector3 VES_POSITION
+		 *	Vector3 VES_NORMAL
+		 * 	32bit index buffer
+		 * 	Enough space for 24 vertices and 36 indices
+		 * @note
+		 * Primitives are output in the form of a triangle list.
+		 */
+		static void solidAABox(const AABox& box, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
+
+		/**
+		 * Fills the mesh data with vertices representing an outline of a sphere.
+		 *
+		 * @param[in]		sphere			Sphere to get the mesh data for
+		 * @param[in, out]	meshData		Mesh data that will be populated.
+		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * @param[in]		quality			Represents the level of tessellation the sphere will have. Higher level means 
+		 *									higher quality but also more vertices and primitives.
+		 *
+		 * @note	
+		 * Provided MeshData must have some specific elements at least:
+		 *  Vector3 VES_POSITION
+		 *  32bit index buffer
+		 *  Enough space for 3 * ((quality + 1) * 5) vertices 
+		 *	Enough space for 6 * ((quality + 1) * 5 - 1) indices
+		 * @note
+		 * Primitives are output in the form of a line list.
+		 */
+		static void wireSphere(const Sphere& sphere, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, 
+			UINT32 quality = 10);
+
+		/**
+		 * Fills the mesh data with vertices representing a sphere.
+		 *
+		 * @param[in]		sphere			Sphere to get the mesh data for
+		 * @param[in, out]	meshData		Mesh data that will be populated.
+		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * @param[in]		quality			Represents the level of tessellation the sphere will have. Higher level means 
+		 *									higher quality but also more vertices and primitives.
+		 *
+		 * @note	
+		 * Provided MeshData must have some specific elements at least:
+		 *  Vector3 VES_POSITION
+		 *	Vector3 VES_NORMAL
+		 * 	32bit index buffer
+		 * 	Enough space for 20 * (4 * (3 ^ quality)) vertices 
+		 *	Enough space for 20 * (4 * (3 ^ quality)) indices
+		 * @note
+		 * Primitives are output in the form of a triangle list.
+		 */
+		static void solidSphere(const Sphere& sphere, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, 
+			UINT32 quality = 1);
+
+		/**
+		 * Fills the mesh data with vertices representing an outline of an arc.
+		 *
+		 * @param[in]		center			Center of the arc to generate geometry for.
+		 * @param[in]		radius			Radius of the arc to generate geometry for.
+		 * @param[in]		normal			Normal around which the arc is generated. Arc geometry will be perpendicular
+		 *									to the normal.
+		 * @param[in]		startAngle		Angle at which the arc starts.
+		 * @param[in]		amountAngle		Angle that the arc spans.
+		 * @param[in, out]	meshData		Mesh data that will be populated.
+		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * @param[in]		quality			Represents the level of tessellation the arc will have. Higher level means
+		 *									higher quality but also more vertices and primitives.
+		 *
+		 * @note	
+		 * Provided MeshData must have some specific elements at least:
+		 *  Vector3 VES_POSITION
+		 *  32bit index buffer
+		 *  Enough space for ((quality + 1) * 5) vertices 
+		 *	Enough space for (((quality + 1) * 5 - 1) * 2) indices
+		 * @note
+		 * Primitives are output in the form of a line list.
+		 */
+		static void wireArc(const Vector3& center, float radius, const Vector3& normal, Degree startAngle, Degree amountAngle,
+			const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality = 10);
+
+		/**
+		 * Fills the mesh data with vertices representing a solid double-sided arc.
+		 *
+		 * @param[in]		center			Center of the arc to generate geometry for.
+		 * @param[in]		radius			Radius of the arc to generate geometry for.
+		 * @param[in]		normal			Normal around which the arc is generated. Arc geometry will be perpendicular to
+		 *									the normal.
+		 * @param[in]		startAngle		Angle at which the arc starts.
+		 * @param[in]		amountAngle		Angle that the arc spans.
+		 * @param[in, out]	meshData		Mesh data that will be populated.
+		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * @param[in]		quality			Represents the level of tessellation the arc will have. Higher level means higher 
+		 *									quality but also more vertices and primitives.
+		 *
+		 * @note	
+		 * Provided MeshData must have some specific elements at least:
+		 *  Vector3 VES_POSITION
+		 *	Vector3 VES_NORMAL
+		 * 	32bit index buffer
+		 * 	Enough space for ((quality + 1) * 5 + 1) * 2 vertices 
+		 *	Enough space for (((quality + 1) * 5 - 1) * 6) indices
+		 * @note
+		 * Primitives are output in the form of a triangle list.
+		 */
+		static void solidArc(const Vector3& center, float radius, const Vector3& normal, Degree startAngle, Degree amountAngle,
+			const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality = 10);
+
+		/**
+		 * Fills the mesh data with vertices representing an outline of a disc.
+		 *
+		 * @param[in]		center			Center of the disc to generate geometry for.
+		 * @param[in]		radius			Radius of the disc to generate geometry for.
+		 * @param[in]		normal			Normal around which the disc is generated. Disc geometry will be perpendicular
+		 *									to the normal.
+		 * @param[in, out]	meshData		Mesh data that will be populated.
+		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * @param[in]		quality			Represents the level of tessellation the disc will have. Higher level means
+		 *									higher quality but also more vertices and primitives.
+		 *
+		 * @note	
+		 * Provided MeshData must have some specific elements at least:
+		 * 	Vector3 VES_POSITION
+		 * 	32bit index buffer
+		 * 	Enough space for ((quality + 1) * 5) vertices 
+		 *	Enough space for (((quality + 1) * 5 - 1) * 2) indices
+		 * @note
+		 * Primitives are output in the form of a line list.
+		 */
+		static void wireDisc(const Vector3& center, float radius, const Vector3& normal, const MeshDataPtr& meshData,
+			UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality = 10);
+
+		/**
+		 * Fills the mesh data with vertices representing a solid double-sided disc.
+		 *
+		 * @param[in]		center			Center of the disc to generate geometry for.
+		 * @param[in]		radius			Radius of the disc to generate geometry for.
+		 * @param[in]		normal			Normal around which the disc is generated. Disc geometry will be perpendicular 
+		 *									to the normal.
+		 * @param[in, out]	meshData		Mesh data that will be populated.
+		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * @param[in]		quality			Represents the level of tessellation the disc will have. Higher level means higher
+		 *									quality but also more vertices and primitives.
+		 *
+		 * @note	
+		 * Provided MeshData must have some specific elements at least:
+		 *  Vector3 VES_POSITION
+		 *	Vector3 VES_NORMAL
+		 * 	32bit index buffer
+		 * 	Enough space for ((quality + 1) * 5 + 1) * 2 vertices 
+		 *	Enough space for (((quality + 1) * 5 - 1) * 6) indices
+		 * @note
+		 * Primitives are output in the form of a triangle list.
+		 */
+		static void solidDisc(const Vector3& center, float radius, const Vector3& normal, const MeshDataPtr& meshData,
+			UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality = 10);
+
+		/**
+		 * Fills the mesh data with vertices representing an outline of an camera frustum. Frustum will be facing -z and be
+		 * positioned at world origin.
+		 *
+		 * @param[in]		position		Starting point for the frustum.
+		 * @param[in]		aspect			Aspect ratio (width / height).
+		 * @param[in]		FOV				Horizontal field of view angle.
+		 * @param[in]		near			Distance to near clipping plane.
+		 * @param[in]		far				Distance to far clipping plane.
+		 * @param[in, out]	meshData		Mesh data that will be populated.
+		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * 							
+		 * @note	
+		 * Provided MeshData must have some specific elements at least:
+		 *  Vector3 VES_POSITION
+		 *  32bit index buffer
+		 *  Enough space for 8 vertices and 24 indices
+		 * @note
+		 * Primitives are output in the form of a line list.
+		 */
+		static void wireFrustum(const Vector3& position, float aspect, Degree FOV, float near, float far,
+			const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
+
+		/**
+		 * Fills the mesh data with vertices representing a wireframe cone.
+		 *
+		 * @param[in]		base			World position of the cone base.
+		 * @param[in]		normal			Direction of the pointed part of the cone.
+		 * @param[in]		height			Cone height (distance from base to the top).
+		 * @param[in]		radius			Cone radius (distance from base center to outer edge).
+		 * @param[in]		scale			Scale to apply to the x/y axes, allowing you to create elliptical cones.
+		 * @param[in, out]	meshData		Mesh data that will be populated.
+		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * @param[in]		quality			Represents the level of tessellation the cone will have. Higher level means 
+		 *									higher quality but also more vertices and primitives.
+		 *
+		 * @note	
+		 * Provided MeshData must have some specific elements at least:
+		 *  Vector3 VES_POSITION
+		 * 	32bit index buffer
+		 * 	Enough space for ((quality + 1) * 4 + 5) vertices
+		 *	Enough space for (((quality + 1) * 4 + 4) * 2) indices
+		 * @note
+		 * Primitives are output in the form of a line list.
+		 */
+		static void wireCone(const Vector3& base, const Vector3& normal, float height, float radius, Vector2 scale,
+			const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality = 10);
+
+		/**
+		 * Fills the mesh data with vertices representing a solid cone.
+		 *
+		 * @param[in]		base			World position of the cone base.
+		 * @param[in]		normal			Direction of the pointed part of the cone.
+		 * @param[in]		height			Cone height (distance from base to the top).
+		 * @param[in]		radius			Cone radius (distance from base center to outer edge).
+		 * @param[in]		scale			Scale to apply to the x/y axes, allowing you to create elliptical cones.
+		 * @param[in, out]	meshData		Mesh data that will be populated.
+		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * @param[in]		quality			Represents the level of tessellation the cone will have. Higher level means 
+		 *									higher quality but also more vertices and primitives.
+		 *
+		 * @note	
+		 * Provided MeshData must have some specific elements at least:
+		 *  Vector3 VES_POSITION
+		 *	Vector3 VES_NORMAL
+		 * 	32bit index buffer
+		 * 	Enough space for ((quality + 1) * 4) * 3 + 1 vertices 
+		 *	Enough space for (((quality + 1) * 4) * 6) indices
+		 * @note
+		 * Primitives are output in the form of a triangle list.
+		 */
+		static void solidCone(const Vector3& base, const Vector3& normal, float height, float radius, Vector2 scale,
+			const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality = 10);
+
+		/**
+		 * Fills the mesh data with vertices representing a quad (4 triangles, two sided).
+		 *
+		 * @param[in]		area			Area in which to draw the quad.
+		 * @param[in, out]	meshData		Mesh data that will be populated.
+		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * 							
+		 * @note	
+		 * Provided MeshData must have some specific elements at least:
+		 *  Vector3 VES_POSITION
+		 *	Vector3 VES_NORMAL
+		 * 	32bit index buffer
+		 * 	Enough space for 8 vertices and 12 indices
+		 * @note
+		 * Primitives are output in the form of a triangle list.
+		 */
+		static void solidQuad(const Rect3& area, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
+
+		/**
+		 * Fills the mesh data with vertices representing a per-pixel line.
+		 *
+		 * @param[in]		a				Start point of the line.
+		 * @param[in]		b				End point of the line.
+		 * @param[in, out]	meshData	Mesh data that will be populated.
+		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * 							
+		 * @note	
+		 * Provided MeshData must have some specific elements at least:
+		 *  Vector3	  VES_POSITION
+		 *  32bit index buffer
+		 *  Enough space for 2 vertices and 2 indices
+		 * @note
+		 * Primitives are output in the form of a line list.
+		 */
+		static void pixelLine(const Vector3& a, const Vector3& b, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
+
+		/**
+		 * Fills the mesh data with vertices representing an anti-aliased line of specific width. Antialiasing is done 
+		 * using alpha blending.
+		 *
+		 * @param[in]		a				Start point of the line.
+		 * @param[in]		b				End point of the line.
+		 * @param[in]		up				Up direction to which the line will run perpendicular to.
+		 * @param[in]		width			Width of the line.
+		 * @param[in]		borderWidth		Width of the anti-aliased border.
+		 * @param[in]		color			Color of the line.
+		 * @param[in, out]	meshData	Mesh data that will be populated by this method.
+		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * 							
+		 * @note	
+		 * Provided MeshData must have some specific elements at least:
+		 *  Vector3 VES_POSITION
+		 *  UINT32  VES_COLOR
+		 *  32bit index buffer
+		 *	Enough space for 8 vertices and 30 indices
+		 * @note
+		 * Primitives are output in the form of a triangle list.
+		 */
+		static void antialiasedLine(const Vector3& a, const Vector3& b, const Vector3& up, float width, float borderWidth, const Color& color,
+			const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
+
+		/**
+		 * Fills the mesh data with vertices representing per-pixel lines.
+		 *
+		 * @param[in]		linePoints		A list of start and end points for the lines. Must be a multiple of 2.
+		 * @param[in, out]	meshData		Mesh data that will be populated.
+		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * 							
+		 * @note	
+		 * Provided MeshData must have some specific elements at least:
+		 *  Vector3  VES_POSITION
+		 *  32bit index buffer
+		 *  Enough space for (numLines * 2) vertices and (numLines * 2) indices
+		 * @note
+		 * Primitives are output in the form of a line list.
+		 */
+		static void pixelLineList(const Vector<Vector3>& linePoints, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
+
+		/**
+		 * Fills the mesh data with vertices representing anti-aliased lines of specific width. Antialiasing is done using
+		 * alpha blending.
+		 *
+		 * @param[in]		linePoints		A list of start and end points for the lines. Must be a multiple of 2.
+		 * @param[in]		up				Up direction to which the line will run perpendicular to.
+		 * @param[in]		width			Width of the line.
+		 * @param[in]		borderWidth		Width of the anti-aliased border.
+		 * @param[in]		color			Color of the line.
+		 * @param[in, out]	meshData		Mesh data that will be populated by this method.
+		 * @param[in]		vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]		indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * 							
+		 * @note	
+		 * Provided MeshData must have some specific elements at least:
+		 *  Vector3 VES_POSITION
+		 *  UINT32  VES_COLOR
+		 *  32bit index buffer
+		 *	Enough space for (numLines * 8) vertices and (numLines * 30) indices
+		 * @note
+		 * Primitives are output in the form of a triangle list.
+		 */
+		static void antialiasedLineList(const Vector<Vector3>& linePoints, const Vector3& up, float width, float borderWidth,
+			const Color& color, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset);
+
+		/**
+		 * Fills the provided buffers with position and index data representing an outline of an axis aligned box. Use 
+		 * getNumElementsWireAABox() to determine the required sizes of the output buffers.
+		 *
+		 * @param[in]	box				Box to create geometry for.
+		 * @param[out]	outVertices		Pre-allocated output buffer that will store the vertex position data.
+		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]	vertexStride	Size of a single vertex, in bytes.
+		 * @param[out]	outIndices		Pre-allocated output buffer that will store the index data. Indices are 32bit.
+		 * @param[in]	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 */
+		static void wireAABox(const AABox& box, UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride,
+			UINT32* outIndices, UINT32 indexOffset);
+
+		/**
+		 * Fills the provided buffers with position and index data representing a solid axis aligned box. Use 
+		 * getNumElementsAABox() to determine the required sizes of the output buffers.
+		 *
+		 * @param[in]	box				Box to create geometry for.
+		 * @param[out]	outVertices		Pre-allocated output buffer that will store the vertex position data.
+		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]	vertexStride	Size of a single vertex, in bytes. (Same for both position and normal buffer)
+		 * @param[out]	outIndices		Pre-allocated output buffer that will store the index data. Indices are 32bit.
+		 * @param[in]	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 */
+		static void solidAABox(const AABox& box, UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride,
+			UINT32* outIndices, UINT32 indexOffset);
+
+		/**
+		 * Fills the provided buffers with position and index data representing a sphere. Use getNumElementsSphere() to
+		 * determine the required sizes of the output buffers.
+		 *
+		 * @param[in]	sphere			Sphere to create geometry for.
+		 * @param[out]	outVertices		Pre-allocated output buffer that will store the vertex position data.
+		 * @param[out]	outNormals		Pre-allocated output buffer that will store the vertex normal data. Can be null if
+		 *								normals aren't needed.
+		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]	vertexStride	Size of a single vertex, in bytes. (Same for both position and normal buffer)
+		 * @param[out]	outIndices		Pre-allocated output buffer that will store the index data. Indices are 32bit.
+		 * @param[in]	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * @param[in]	quality			Represents the level of tessellation the sphere will have. Higher level means higher
+		 *								quality but also more vertices and primitives.
+		 */
+		static void solidSphere(const Sphere& sphere, UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride,
+			UINT32* outIndices, UINT32 indexOffset, UINT32 quality);
+
+		/**
+		 * Fills the provided buffers with position and index data representing an outline of an arc. Use
+		 * getNumElementWiresArc() to determine the required sizes of the output buffers.
+		 *
+		 * @param[in]	center			Center of the arc to generate geometry for.
+		 * @param[in]	radius			Radius of the arc to generate geometry for.
+		 * @param[in]	normal			Normal around which the arc is generated. Arc geometry will be perpendicular to the
+		 *								normal.
+		 * @param[in]	startAngle		Angle at which the arc starts.
+		 * @param[in]	amountAngle		Angle that the arc spans.
+		 * @param[out]	outVertices		Pre-allocated output buffer that will store the vertex position data.
+		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]	vertexStride	Size of a single vertex, in bytes.
+		 * @param[out]	outIndices		Pre-allocated output buffer that will store the index data. Indices are 32bit.
+		 * @param[in]	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * @param[in]	quality			Represents the level of tessellation the arc will have. Higher level means higher
+		 *								quality but also more vertices and primitives.
+		 */
+		static void wireArc(const Vector3& center, float radius, const Vector3& normal, Degree startAngle, Degree amountAngle,
+			UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset, UINT32 quality);
+
+		/**
+		 * Fills the provided buffers with position and index data representing a solid arc. Use getNumElementsArc() to
+		 * determine the required sizes of the output buffers.
+		 *
+		 * @param[in]	center			Center of the arc to generate geometry for.
+		 * @param[in]	radius			Radius of the arc to generate geometry for.
+		 * @param[in]	normal			Normal around which the arc is generated. Arc geometry will be perpendicular to the
+		 *								normal.
+		 * @param[in]	startAngle		Angle at which the arc starts.
+		 * @param[in]	amountAngle		Angle that the arc spans.
+		 * @param[out]	outVertices		Pre-allocated output buffer that will store the vertex position data.
+		 * @param[out]	outNormals		Pre-allocated output buffer that will store the vertex normal data.
+		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]	vertexStride	Size of a single vertex, in bytes. (Same for both position and normal buffer)
+		 * @param[out]	outIndices		Pre-allocated output buffer that will store the index data. Indices are 32bit.
+		 * @param[in]	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * @param[in]	quality			Represents the level of tessellation the arc will have. Higher level means higher
+		 *								quality but also more vertices and primitives.
+		 */
+		static void solidArc(const Vector3& center, float radius, const Vector3& normal, Degree startAngle, Degree amountAngle,
+			UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset, UINT32 quality);
+
+		/**
+		 * Fills the provided buffers with position and index data representing an outline of a camera frustum. Use
+		 * getNumElementsFrustum() to determine the required sizes of the output buffers.
+		 *
+		 * @param[in]	position		Starting point for the frustum.
+		 * @param[in]	aspect			Aspect ratio (width / height).
+		 * @param[in]	FOV				Horizontal field of view angle.
+		 * @param[in]	near			Distance to near clipping plane.
+		 * @param[in]	far				Distance to far clipping plane.
+		 * @param[out]	outVertices		Pre-allocated output buffer that will store the vertex position data.
+		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]	vertexStride	Size of a single vertex, in bytes.
+		 * @param[out]	outIndices		Pre-allocated output buffer that will store the index data. Indices are 32bit.
+		 * @param[in]	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 */
+		static void wireFrustum(const Vector3& position, float aspect, Degree FOV, float near, float far,
+			UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
+
+		/**
+		 * Fills the provided buffers with position and index data representing a solid cone. Use getNumElementsCone() to
+		 * determine the required sizes of the output buffers.
+		 *
+		 * @param[in]	base			World position of the cone base.
+		 * @param[in]	normal			Direction of the pointed part of the cone.
+		 * @param[in]	height			Cone height (distance from base to the top).
+		 * @param[in]	radius			Cone radius (distance from base center to outer edge).
+		 * @param[in]	scale			Scale to apply to the x/y axes, allowing you to create elliptical cones.
+		 * @param[out]	outVertices		Pre-allocated output buffer that will store the vertex position data.
+		 * @param[out]	outNormals		Pre-allocated output buffer that will store the vertex normal data. Can be null if
+		 *								normals aren't needed.
+		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]	vertexStride	Size of a single vertex, in bytes. (Same for both position and normal buffer)
+		 * @param[out]	outIndices		Pre-allocated output buffer that will store the index data. Indices are 32bit.
+		 * @param[in]	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * @param[in]	quality			Represents the level of tessellation the cone will have. Higher level means higher
+		 *								quality but also more vertices and primitives.
+		 */
+		static void solidCone(const Vector3& base, const Vector3& normal, float height, float radius, Vector2 scale,
+			UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, 
+			UINT32 indexOffset, UINT32 quality);
+
+		/**
+		 * Fills the provided buffers with position and index data representing a wire cone. Use getNumElementsWireCone() to
+		 * determine the required sizes of the output buffers.
+		 *
+		 * @param[in]	base			World position of the cone base.
+		 * @param[in]	normal			Direction of the pointed part of the cone.
+		 * @param[in]	height			Cone height (distance from base to the top).
+		 * @param[in]	radius			Cone radius (distance from base center to outer edge).
+		 * @param[in]	scale			Scale to apply to the x/y axes, allowing you to create elliptical cones.
+		 * @param[out]	outVertices		Pre-allocated output buffer that will store the vertex position data.
+		 * @param[out]	outNormals		Pre-allocated output buffer that will store the vertex normal data. Can be null if
+		 *								normals aren't needed.
+		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]	vertexStride	Size of a single vertex, in bytes. (Same for both position and normal buffer)
+		 * @param[out]	outIndices		Pre-allocated output buffer that will store the index data. Indices are 32bit.
+		 * @param[in]	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 * @param[in]	quality			Represents the level of tessellation the cone will have. Higher level means higher
+		 *								quality but also more vertices and primitives.
+		 */
+		static void wireCone(const Vector3& base, const Vector3& normal, float height, float radius, Vector2 scale,
+			UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset, 
+			UINT32 quality);
+
+		/**
+		 * Fills the provided buffers with position and index data representing a solid quad. Use getNumElementsCone() to
+		 * determine the required sizes of the output buffers.
+		 *
+		 * @param[in]	area			Area covered by the quad.
+		 * @param[out]	outVertices		Pre-allocated output buffer that will store the vertex position data.
+		 * @param[out]	outNormals		Pre-allocated output buffer that will store the vertex normal data.
+		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]	vertexStride	Size of a single vertex, in bytes. (Same for both position and normal buffer)
+		 * @param[out]	outIndices		Pre-allocated output buffer that will store the index data. Indices are 32bit.
+		 * @param[in]	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 */
+		static void solidQuad(const Rect3& area, UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
+
+		/**	Calculates number of vertices and indices required for geometry of a solid axis aligned box. */
+		static void getNumElementsAABox(UINT32& numVertices, UINT32& numIndices);
+
+		/**	Calculates number of vertices and indices required for geometry of a wireframe axis aligned box. */
+		static void getNumElementsWireAABox(UINT32& numVertices, UINT32& numIndices);
+
+		/**	Calculates number of vertices and indices required for geometry of a solid sphere of the specified quality. */
+		static void getNumElementsSphere(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
+
+		/**	Calculates number of vertices and indices required for geometry of a wire sphere of the specified quality. */
+		static void getNumElementsWireSphere(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
+
+		/**	Calculates number of vertices and indices required for geometry of a solid arc of the specified quality. */
+		static void getNumElementsArc(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
+
+		/**	Calculates number of vertices and indices required for geometry of a wire arc of the specified quality. */
+		static void getNumElementsWireArc(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
+
+		/**	Calculates number of vertices and indices required for geometry of a solid desc	of the specified quality. */
+		static void getNumElementsDisc(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
+
+		/**	Calculates number of vertices and indices required for geometry of a wire disc of the specified quality. */
+		static void getNumElementsWireDisc(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
+
+		/**	Calculates number of vertices and indices required for geometry of a solid cone of the specified quality. */
+		static void getNumElementsCone(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
+
+		/**	Calculates number of vertices and indices required for geometry of a wireframe cone of the specified quality. */
+		static void getNumElementsWireCone(UINT32 quality, UINT32& numVertices, UINT32& numIndices);
+
+		/**	Calculates number of vertices and indices required for geometry of a frustum. */
+		static void getNumElementsFrustum(UINT32& numVertices, UINT32& numIndices);
+
+		/**	Calculates number of vertices and indices required for geometry of a quadrirateral. */
+		static void getNumElementsQuad(UINT32& numVertices, UINT32& numIndices);
+
+		static const UINT32 NUM_VERTICES_AA_LINE;
+		static const UINT32 NUM_INDICES_AA_LINE;
+
+	protected:
+		/**
+		 * Fills the provided buffers with vertices representing a per-pixel line.
+		 *
+		 * @param[in]	a				Start point of the line.
+		 * @param[in]	b				End point of the line.
+		 * @param[out]	outVertices		Output buffer that will store the vertex position data.
+		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
+		 * @param[out]	outIndices		Output buffer that will store the index data. Indices are 32bit.
+		 * @param[in]	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 */
+		static void pixelLine(const Vector3& a, const Vector3& b, UINT8* outVertices,
+			UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
+
+		/**
+		 * Fills the provided buffers with vertices representing an antialiased line with a custom width.
+		 *
+		 * @param[in]	a				Start point of the line.
+		 * @param[in]	b				End point of the line.
+		 * @param[in]	up				Up direction to which the line will run perpendicular to.
+		 * @param[in]	width			Width of the line.
+		 * @param[in]	borderWidth		Width of the anti-aliased border.
+		 * @param[in]	color			Color of the line.
+		 * @param[out]	outVertices		Output buffer that will store the vertex position data.
+		 * @param[out]	outColors		Output buffer that will store the vertex color data.
+		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
+		 * @param[out]	outIndices		Output buffer that will store the index data. Indices are 32bit.
+		 * @param[in]	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 */
+		static void antialiasedLine(const Vector3& a, const Vector3& b, const Vector3& up, float width, float borderWidth, 
+			const Color& color, UINT8* outVertices, UINT8* outColors, UINT32 vertexOffset, UINT32 vertexStride, 
+			UINT32* outIndices, UINT32 indexOffset);
+
+		/**
+		 * Fills the provided buffers with position data and indices representing an inner area of a polygon (basically a
+		 * normal non-antialiased polygon).
+		 *
+		 * @param[in]	points			Points defining the polygon. First point is assumed to be the start and end point.
+		 * @param[out]	outVertices		Output buffer that will store the vertex position data.
+		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
+		 * @param[out]	outIndices		Output buffer that will store the index data. Indices are 32bit.
+		 * @param[in]	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 */
+		static void pixelSolidPolygon(const Vector<Vector3>& points, UINT8* outVertices,
+			UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
+
+		/**
+		 * Fills the provided buffers with vertices representing a pixel-wide polygon border.
+		 *
+		 * @param[in]	points			Points defining the polygon. First point is assumed to be the start and end point.
+		 * @param[out]	outVertices		Output buffer that will store the vertex position data.
+		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
+		 * @param[out]	outIndices		Output buffer that will store the index data. Indices are 32bit.
+		 * @param[in]	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 */
+		static void pixelWirePolygon(const Vector<Vector3>& points, UINT8* outVertices,
+			UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
+
+		/**
+		 * Fills the provided buffers with vertices representing an antialiased polygon.
+		 *
+		 * @param[in]	points			Points defining the polygon. First point is assumed to be the start and end point.
+		 * @param[in]	up				Up direction to which the polygon will run perpendicular to.
+		 * @param[in]	borderWidth		Width of the anti-aliased border.
+		 * @param[in]	color			Color of the polygon.
+		 * @param[out]	outVertices		Output buffer that will store the vertex position data.
+		 * @param[out]	outColors		Output buffer that will store the vertex color data.
+		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
+		 * @param[out]	outIndices		Output buffer that will store the index data. Indices are 32bit.
+		 * @param[in]	indexOffset 	Offset in number of indices from the start of the buffer to start writing at.
+		 */
+		static void antialiasedPolygon(const Vector<Vector3>& points, const Vector3& up, float borderWidth, const Color& color, UINT8* outVertices, UINT8* outColors,
+			UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset);
+
+	private:
+		/**
+		 * Calculates the center of the provided vertices.
+		 * 
+		 * @param[in]	vertices		Buffer containing vertices. Vertices must be of three dimensions at least.
+		 * @param[in]	numVertices		Number of vertices to calculate the center for.
+		 * @param[in]	vertexStride	Number of bytes between two vertices in the buffer.
+		 * @return						Center point of the vertices.
+		 */
+		static Vector3 calcCenter(UINT8* vertices, UINT32 numVertices, UINT32 vertexStride);
+
+		/**
+		 * Subdivides the provided triangle so it approximates a curved surface of a sphere.
+		 *
+		 * @param[in]	center			Center of the sphere to approximate.
+		 * @param[in]	radius			Radius of the sphere to approximate.
+		 * @param[in]	numLevels		Number of times to subdivide the triangle. Higher number means better approximation.
+		 * @param[in]	a				First corner of the triangle. Must be normalized.
+		 * @param[in]	b				Second corner of the triangle. Must be normalized.
+		 * @param[in]	c				Third corner of the triangle. Must be normalized.
+		 * @param[out]	outVertices		Output buffer that will store the vertex position data.
+		 * @param[out]	outNormals		Output buffer that will store the vertex normal data.
+		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
+		 * @return						Number of vertices generated (3 * (4 ^ numLevels)).
+		 */
+		static UINT32 subdivideTriangleOnSphere(const Vector3& center, float radius, UINT32 numLevels,
+			const Vector3& a, const Vector3& b, const Vector3& c,
+			UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride);
+
+		/**
+		 * Generates vertices that are part of an arc approximation.
+		 *
+		 * @param[in]	center			Determines world position of the arc.
+		 * @param[in]	up				Determines rotation of the arc. Arc vertices will be perpendicular to this 
+		 *								direction.
+		 * @param[in]	radius			Distance of arc vertices from the center.
+		 * @param[in]	startAngle		Angle in degrees to start the arc at.
+		 * @param[in]	angleAmount		Angle in degrees to extend the arc from the start angle.
+		 * @param[in]	scale			Scale to apply to the x/y axes, allowing you to create elliptical arcs.
+		 * @param[in]	numVertices		Number of vertices to generate for the arc. Higher number means better arc 
+		 *								approximation. Must be 2 or higher.
+		 * @param[out]	outVertices		Output buffer that will store the vertex position data.
+		 * @param[in]	vertexOffset	Offset in number of vertices from the start of the buffer to start writing at.
+		 * @param[in]	vertexStride	Size of a single vertex, in bytes. (Same for both position and color buffer)
+		 */
+		static void generateArcVertices(const Vector3& center, const Vector3& up, float radius, Degree startAngle, 
+			Degree angleAmount, Vector2 scale, UINT32 numVertices, UINT8* outvertices, UINT32 vertexOffset, UINT32 vertexStride);
+	};
+
+	/** @} */
 }

+ 57 - 4
Source/BansheeEngine/Source/BsDrawHelper.cpp

@@ -167,7 +167,8 @@ namespace BansheeEngine
 		frustumData.center = mTransform.multiplyAffine(position);
 	}
 
-	void DrawHelper::cone(const Vector3& base, const Vector3& normal, float height, float radius, UINT32 quality)
+	void DrawHelper::cone(const Vector3& base, const Vector3& normal, float height, float radius, const Vector2& scale, 
+		UINT32 quality)
 	{
 		mConeData.push_back(ConeData());
 		ConeData& coneData = mConeData.back();
@@ -176,6 +177,25 @@ namespace BansheeEngine
 		coneData.normal = normal;
 		coneData.height = height;
 		coneData.radius = radius;
+		coneData.scale = scale;
+		coneData.quality = quality;
+		coneData.color = mColor;
+		coneData.transform = mTransform;
+		coneData.layer = mLayer;
+		coneData.center = mTransform.multiplyAffine(base + normal * height * 0.5f);
+	}
+
+	void DrawHelper::wireCone(const Vector3& base, const Vector3& normal, float height, float radius, const Vector2& scale,
+		UINT32 quality)
+	{
+		mWireConeData.push_back(ConeData());
+		ConeData& coneData = mWireConeData.back();
+
+		coneData.base = base;
+		coneData.normal = normal;
+		coneData.height = height;
+		coneData.radius = radius;
+		coneData.scale = scale;
 		coneData.quality = quality;
 		coneData.color = mColor;
 		coneData.transform = mTransform;
@@ -310,6 +330,7 @@ namespace BansheeEngine
 		mArcData.clear();
 		mWireArcData.clear();
 		mConeData.clear();
+		mWireConeData.clear();
 		mText2DData.clear();
 		mWireMeshData.clear();
 	}
@@ -320,7 +341,7 @@ namespace BansheeEngine
 
 		enum class ShapeType
 		{
-			Cube, Sphere, WireCube, WireSphere, Line, LineList, Frustum, 
+			Cube, Sphere, WireCube, WireSphere, WireCone, Line, LineList, Frustum, 
 			Cone, Disc, WireDisc, Arc, WireArc, Rectangle, Text, WireMesh
 		};
 
@@ -515,6 +536,28 @@ namespace BansheeEngine
 				rawData.numVertices, rawData.numIndices);
 		}
 
+		localIdx = 0;
+		for (auto& shapeData : mWireConeData)
+		{
+			if ((shapeData.layer & layers) == 0)
+			{
+				localIdx++;
+				continue;
+			}
+
+			allShapes.push_back(RawData());
+			RawData& rawData = allShapes.back();
+
+			rawData.idx = localIdx++;
+			rawData.textIdx = 0;
+			rawData.meshType = MeshType::Line;
+			rawData.shapeType = ShapeType::WireCone;
+			rawData.distance = shapeData.center.distance(reference);
+
+			ShapeMeshes3D::getNumElementsWireCone(shapeData.quality,
+				rawData.numVertices, rawData.numIndices);
+		}
+
 		localIdx = 0;
 		for (auto& shapeData : mLineData)
 		{
@@ -829,8 +872,8 @@ namespace BansheeEngine
 					case ShapeType::Cone:
 					{
 						ConeData& coneData = mConeData[shapeData.idx];
-						ShapeMeshes3D::solidCone(coneData.base, coneData.normal, coneData.height, coneData.radius,
-							meshData, curVertexOffset, curIndexOffet, coneData.quality);
+						ShapeMeshes3D::solidCone(coneData.base, coneData.normal, coneData.height, coneData.radius, 
+							coneData.scale, meshData, curVertexOffset, curIndexOffet, coneData.quality);
 
 						transform = &coneData.transform;
 						color = coneData.color.getAsRGBA();
@@ -984,6 +1027,16 @@ namespace BansheeEngine
 						color = sphereData.color.getAsRGBA();
 					}
 						break;
+					case ShapeType::WireCone:
+					{
+						ConeData& coneData = mWireConeData[shapeData.idx];
+						ShapeMeshes3D::wireCone(coneData.base, coneData.normal, coneData.height, coneData.radius,
+							coneData.scale, meshData, curVertexOffset, curIndexOffet, coneData.quality);
+
+						transform = &coneData.transform;
+						color = coneData.color.getAsRGBA();
+					}
+					break;
 					case ShapeType::Line:
 					{
 						LineData& lineData = mLineData[shapeData.idx];

+ 75 - 10
Source/BansheeEngine/Source/BsShapeMeshes3D.cpp

@@ -150,7 +150,7 @@ namespace BansheeEngine
 		wireFrustum(position, aspect, FOV, near, far, positionData, vertexOffset, meshData->getVertexDesc()->getVertexStride(), indexData, indexOffset);
 	}
 
-	void ShapeMeshes3D::solidCone(const Vector3& base, const Vector3& normal, float height, float radius,
+	void ShapeMeshes3D::solidCone(const Vector3& base, const Vector3& normal, float height, float radius, Vector2 scale,
 		const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality)
 	{
 		UINT32* indexData = meshData->getIndices32();
@@ -163,7 +163,23 @@ namespace BansheeEngine
 		assert((vertexOffset + requiredNumVertices) <= meshData->getNumVertices());
 		assert((indexOffset + requiredNumIndices) <= meshData->getNumIndices());
 
-		solidCone(base, normal, height, radius, positionData, normalData, vertexOffset,
+		solidCone(base, normal, height, radius, scale, positionData, normalData, vertexOffset,
+			meshData->getVertexDesc()->getVertexStride(), indexData, indexOffset, quality);
+	}
+
+	void ShapeMeshes3D::wireCone(const Vector3& base, const Vector3& normal, float height, float radius, Vector2 scale,
+		const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset, UINT32 quality)
+	{
+		UINT32* indexData = meshData->getIndices32();
+		UINT8* positionData = meshData->getElementData(VES_POSITION);
+
+		UINT32 requiredNumVertices, requiredNumIndices;
+		getNumElementsWireCone(quality, requiredNumVertices, requiredNumIndices);
+
+		assert((vertexOffset + requiredNumVertices) <= meshData->getNumVertices());
+		assert((indexOffset + requiredNumIndices) <= meshData->getNumIndices());
+
+		wireCone(base, normal, height, radius, scale, positionData, vertexOffset,
 			meshData->getVertexDesc()->getVertexStride(), indexData, indexOffset, quality);
 	}
 
@@ -309,6 +325,12 @@ namespace BansheeEngine
 		numIndices = ((quality + 1) * 4) * 6;
 	}
 
+	void ShapeMeshes3D::getNumElementsWireCone(UINT32 quality, UINT32& numVertices, UINT32& numIndices)
+	{
+		numVertices = (quality + 1) * 4 + 5;
+		numIndices = ((quality + 1) * 4 + 4) * 2;
+	}
+
 	void ShapeMeshes3D::getNumElementsQuad(UINT32& numVertices, UINT32& numIndices)
 	{
 		numVertices = 8;
@@ -510,7 +532,7 @@ namespace BansheeEngine
 	{
 		UINT32 numVertices = (quality + 1) * 5;
 
-		generateArcVertices(center, normal, radius, startAngle, amountAngle,
+		generateArcVertices(center, normal, radius, startAngle, amountAngle, Vector2::ONE,
 			numVertices, outVertices, vertexOffset, vertexStride);
 
 		outIndices += indexOffset;
@@ -536,7 +558,7 @@ namespace BansheeEngine
 		outNormals = writeVector3(outNormals, vertexStride, visibleNormal);
 
 		UINT32 numArcVertices = (quality + 1) * 5;
-		generateArcVertices(center, normal, radius, startAngle, amountAngle,
+		generateArcVertices(center, normal, radius, startAngle, amountAngle, Vector2::ONE,
 			numArcVertices, outVertices, vertexOffset, vertexStride);
 
 		UINT8* otherSideVertices = outVertices + (numArcVertices * vertexStride);
@@ -623,7 +645,7 @@ namespace BansheeEngine
 		outIndices[22] = vertexOffset + 7; outIndices[23] = vertexOffset + 4;
 	}
 
-	void ShapeMeshes3D::solidCone(const Vector3& base, const Vector3& normal, float height, float radius,
+	void ShapeMeshes3D::solidCone(const Vector3& base, const Vector3& normal, float height, float radius, Vector2 scale,
 		UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset, UINT32 quality)
 	{
 		outVertices += vertexOffset * vertexStride;
@@ -635,7 +657,7 @@ namespace BansheeEngine
 		// Generate base disc
 		UINT32 numArcVertices = (quality + 1) * 4;
 
-		generateArcVertices(base, normal, radius, Degree(0), Degree(360),
+		generateArcVertices(base, normal, radius, Degree(0), Degree(360), scale,
 			numArcVertices + 1, outVertices, 0, vertexStride);
 
 		outVertices += numArcVertices * vertexStride;
@@ -667,7 +689,7 @@ namespace BansheeEngine
 
 		//// Generate cone
 		// Base vertices
-		generateArcVertices(base, normal, radius, Degree(0), Degree(360),
+		generateArcVertices(base, normal, radius, Degree(0), Degree(360), scale,
 			numArcVertices + 1, outVertices, 0, vertexStride);
 
 		Vector3 topVertex = base + normal * height;
@@ -726,6 +748,46 @@ namespace BansheeEngine
 		}
 	}
 
+	void ShapeMeshes3D::wireCone(const Vector3& base, const Vector3& normal, float height, float radius, Vector2 scale,
+		UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset, UINT32 quality)
+	{
+		outVertices += vertexOffset * vertexStride;
+		outIndices += indexOffset;
+
+		// Generate arc vertices
+		UINT32 numArcVertices = (quality + 1) * 4;
+
+		generateArcVertices(base, normal, radius, Degree(0), Degree(360), scale,
+			numArcVertices + 1, outVertices, 0, vertexStride);
+
+		outVertices += numArcVertices * vertexStride;
+
+		UINT32 numLines = numArcVertices;
+		for (UINT32 i = 0; i < numLines; i++)
+		{
+			outIndices[i * 2 + 0] = vertexOffset + i;
+			outIndices[i * 2 + 1] = vertexOffset + i + 1;
+		}
+
+		outIndices += numLines * 2;
+
+		// Generate cone vertices
+		generateArcVertices(base, normal, radius, Degree(0), Degree(360), scale,
+			5, outVertices, 0, vertexStride);
+
+		// Cone point
+		outVertices += 4 * vertexStride;
+		outVertices = writeVector3(outVertices, vertexStride, base + normal * height);
+
+		vertexOffset += numArcVertices;
+
+		for (UINT32 i = 0; i < 4; i++)
+		{
+			outIndices[i * 2 + 0] = vertexOffset + 4;
+			outIndices[i * 2 + 1] = vertexOffset + i;
+		}
+	}
+
 	void ShapeMeshes3D::solidQuad(const Rect3& area, UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
 	{
 		outVertices += (vertexOffset * vertexStride);
@@ -1018,8 +1080,8 @@ namespace BansheeEngine
 		return numVertices;
 	}
 
-	void ShapeMeshes3D::generateArcVertices(const Vector3& center, const Vector3& up, float radius, Degree startAngle, Degree angleAmount, UINT32 numVertices,
-		UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride)
+	void ShapeMeshes3D::generateArcVertices(const Vector3& center, const Vector3& up, float radius, Degree startAngle, 
+		Degree angleAmount, Vector2 scale, UINT32 numVertices, UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride)
 	{
 		assert(numVertices >= 2);
 		
@@ -1029,13 +1091,16 @@ namespace BansheeEngine
 		Vector3 right = alignWithUp.rotate(alignWithStart.rotate(Vector3::UNIT_X));
 		right.normalize();
 
+		Vector3 scale3(scale.x, 0.0f, scale.y);
+		scale3 = alignWithUp.rotate(scale3);
+
 		Quaternion increment(up, angleAmount / (float)(numVertices - 1));
 
 		outVertices += vertexOffset * vertexStride;
 		Vector3 curDirection = right * radius;
 		for (UINT32 i = 0; i < numVertices; i++)
 		{
-			outVertices = writeVector3(outVertices, vertexStride, center + curDirection);
+			outVertices = writeVector3(outVertices, vertexStride, (center + curDirection) * scale3);
 			curDirection = increment.rotate(curDirection);
 		}
 	}

+ 58 - 0
Source/MBansheeEditor/Scene/Gizmos.cs

@@ -68,6 +68,32 @@ namespace BansheeEditor
             Internal_DrawSphere(ref position, radius);
         }
 
+        /// <summary>
+        /// Draws a solid cone.
+        /// </summary>
+        /// <param name="coneBase">Position of the center of the base of the cone.</param>
+        /// <param name="normal">Orientation of the cone, pointing from center base to the tip of the cone.</param>
+        /// <param name="height">Height of the cone (along the normal).</param>
+        /// <param name="radius">Radius of the base of the cone.</param>
+        public static void DrawCone(Vector3 coneBase, Vector3 normal, float height, float radius)
+        {
+            Vector2 scale = Vector2.One;
+            Internal_DrawCone(ref coneBase, ref normal, height, radius, ref scale);
+        }
+
+        /// <summary>
+        /// Draws a solid cone.
+        /// </summary>
+        /// <param name="coneBase">Position of the center of the base of the cone.</param>
+        /// <param name="normal">Orientation of the cone, pointing from center base to the tip of the cone.</param>
+        /// <param name="height">Height of the cone (along the normal).</param>
+        /// <param name="radius">Radius of the base of the cone.</param>
+        /// <param name="scale">Scale applied to cone's disc width & height. Allows you to create elliptical cones.</param>
+        public static void DrawCone(Vector3 coneBase, Vector3 normal, float height, float radius, Vector2 scale)
+        {
+            Internal_DrawCone(ref coneBase, ref normal, height, radius, ref scale);
+        }
+
         /// <summary>
         /// Draws an axis aligned wireframe cube.
         /// </summary>
@@ -99,6 +125,32 @@ namespace BansheeEditor
             Internal_DrawWireCapsule(ref position, height, radius);
         }
 
+        /// <summary>
+        /// Draws a wireframe cone.
+        /// </summary>
+        /// <param name="coneBase">Position of the center of the base of the cone.</param>
+        /// <param name="normal">Orientation of the cone, pointing from center base to the tip of the cone.</param>
+        /// <param name="height">Height of the cone (along the normal).</param>
+        /// <param name="radius">Radius of the base of the cone.</param>
+        public static void DrawWireCone(Vector3 coneBase, Vector3 normal, float height, float radius)
+        {
+            Vector2 scale = Vector2.One;
+            Internal_DrawWireCone(ref coneBase, ref normal, height, radius, ref scale);
+        }
+
+        /// <summary>
+        /// Draws a wireframe cone.
+        /// </summary>
+        /// <param name="coneBase">Position of the center of the base of the cone.</param>
+        /// <param name="normal">Orientation of the cone, pointing from center base to the tip of the cone.</param>
+        /// <param name="height">Height of the cone (along the normal).</param>
+        /// <param name="radius">Radius of the base of the cone.</param>
+        /// <param name="scale">Scale applied to cone's disc width & height. Allows you to create elliptical cones.</param>
+        public static void DrawWireCone(Vector3 coneBase, Vector3 normal, float height, float radius, Vector2 scale)
+        {
+            Internal_DrawWireCone(ref coneBase, ref normal, height, radius, ref scale);
+        }
+
         /// <summary>
         /// Draws a 3D line.
         /// </summary>
@@ -214,6 +266,9 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_DrawSphere(ref Vector3 position, float radius);
 
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_DrawCone(ref Vector3 coneBase, ref Vector3 normal, float height, float radius, ref Vector2 scale);
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_DrawWireCube(ref Vector3 position, ref Vector3 extents);
 
@@ -223,6 +278,9 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_DrawWireCapsule(ref Vector3 position, float height, float radius);
 
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_DrawWireCone(ref Vector3 coneBase, ref Vector3 normal, float height, float radius, ref Vector2 scale);
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_DrawLine(ref Vector3 start, ref Vector3 end);
 

+ 252 - 3
Source/MBansheeEditor/Scene/Gizmos/JointGizmos.cs

@@ -1,6 +1,255 @@
-namespace BansheeEditor
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+
+using System;
+using BansheeEngine;
+
+namespace BansheeEditor
 {
-    class JointGizmos
+    /// <summary>
+    /// Handles drawing of gizmos for all the types of <see cref="Joint"/> component.
+    /// </summary>
+    internal class JointGizmos
     {
+        /// <summary>
+        /// Returns the anchor position for the specified joint body. Anchor represents the world position of the rigidbody
+        /// added to the offset provided by the joint.
+        /// </summary>
+        /// <param name="joint">Joint from which to retrieve the body.</param>
+        /// <param name="body">Body to retrieve the anchor for.</param>
+        /// <returns>Anchor position in world space.</returns>
+        private static Vector3 GetAnchor(Joint joint, JointBody body)
+        {
+            Rigidbody rigidbody = joint.GetRigidbody(body);
+            Vector3 anchor = joint.GetPosition(body);
+
+            if (rigidbody != null)
+            {
+                Quaternion worldRot = rigidbody.SceneObject.Rotation;
+
+                anchor = worldRot.Rotate(anchor) + rigidbody.SceneObject.Position;
+            }
+
+            return anchor;
+        }
+
+        /// <summary>
+        /// Method called by the runtime when joints are meant to be drawn.
+        /// </summary>
+        /// <param name="joint">Joint to draw gizmos for.</param>
+        [DrawGizmo(DrawGizmoFlags.Selected | DrawGizmoFlags.ParentSelected)]
+        private static void DrawFixedJoint(FixedJoint joint)
+        {
+            Vector3 anchorA = GetAnchor(joint, JointBody.A);
+            Vector3 anchorB = GetAnchor(joint, JointBody.B);
+
+            Gizmos.Color = Color.White;
+            Gizmos.DrawSphere(anchorA, 0.05f);
+            Gizmos.DrawSphere(anchorB, 0.05f);
+
+            Gizmos.Color = Color.Green;
+            Gizmos.DrawLine(anchorA, anchorB);
+        }
+
+        /// <summary>
+        /// Method called by the runtime when joints are meant to be drawn.
+        /// </summary>
+        /// <param name="joint">Joint to draw gizmos for.</param>
+        [DrawGizmo(DrawGizmoFlags.Selected | DrawGizmoFlags.ParentSelected)]
+        private static void DrawDistanceJoint(DistanceJoint joint)
+        {
+            Vector3 anchorA = GetAnchor(joint, JointBody.A);
+            Vector3 anchorB = GetAnchor(joint, JointBody.B);
+
+            Gizmos.Color = Color.White;
+            Gizmos.DrawSphere(anchorA, 0.05f);
+            Gizmos.DrawSphere(anchorB, 0.05f);
+
+            Gizmos.Color = Color.Red;
+            Vector3 diff = anchorB - anchorA;
+
+            float length = diff.Length;
+            Vector3 normal = diff.Normalized;
+
+            float min = 0.0f;
+            float max = length;
+
+            Vector3 center = anchorA + diff*0.5f;
+            if (joint.EnableMinDistanceLimit)
+            {
+                min = MathEx.Max(0.0f, joint.MinDistance);
+
+                Gizmos.DrawLine(center - normal*min*0.5f, center + normal*min*0.5f);
+            }
+
+            if (joint.EnableMaxDistanceLimit)
+            {
+                max = MathEx.Min(10000.0f, joint.MaxDistance);
+
+                Gizmos.DrawLine(center - normal * max * 0.5f, center - normal * length * 0.5f);
+                Gizmos.DrawLine(center + normal * max * 0.5f, center + normal * length * 0.5f);
+            }
+
+            Gizmos.Color = Color.Green;
+            Gizmos.DrawLine(center - normal * min * 0.5f, center - normal * max * 0.5f);
+            Gizmos.DrawLine(center + normal * min * 0.5f, center + normal * max * 0.5f);
+        }
+
+        /// <summary>
+        /// Method called by the runtime when joints are meant to be drawn.
+        /// </summary>
+        /// <param name="joint">Joint to draw gizmos for.</param>
+        [DrawGizmo(DrawGizmoFlags.Selected | DrawGizmoFlags.ParentSelected)]
+        private static void DrawSliderJoint(SliderJoint joint)
+        {
+            Vector3 anchorA = GetAnchor(joint, JointBody.A);
+            Vector3 anchorB = GetAnchor(joint, JointBody.B);
+
+            Gizmos.Color = Color.White;
+            Gizmos.DrawSphere(anchorA, 0.05f);
+            Gizmos.DrawSphere(anchorB, 0.05f);
+
+            Gizmos.Color = Color.Red;
+            Vector3 diff = anchorB - anchorA;
+
+            float length = diff.Length;
+            Vector3 normal = diff.Normalized;
+
+            float min = 0.0f;
+            float max = length;
+
+            Vector3 center = anchorA + diff * 0.5f;
+            if (joint.EnableLimit)
+            {
+                LimitLinearRange limit = joint.Limit;
+
+                min = MathEx.Max(0.0f, limit.Lower);
+                Gizmos.DrawLine(center - normal * min * 0.5f, center + normal * min * 0.5f);
+
+                max = MathEx.Min(10000.0f, limit.Upper);
+
+                Gizmos.DrawLine(center - normal * max * 0.5f, center - normal * length * 0.5f);
+                Gizmos.DrawLine(center + normal * max * 0.5f, center + normal * length * 0.5f);
+            }
+
+            Gizmos.Color = Color.Green;
+            Gizmos.DrawLine(center - normal * min * 0.5f, center - normal * max * 0.5f);
+            Gizmos.DrawLine(center + normal * min * 0.5f, center + normal * max * 0.5f);
+        }
+
+        /// <summary>
+        /// Method called by the runtime when joints are meant to be drawn.
+        /// </summary>
+        /// <param name="joint">Joint to draw gizmos for.</param>
+        [DrawGizmo(DrawGizmoFlags.Selected | DrawGizmoFlags.ParentSelected)]
+        private static void DrawSphericalJoint(SphericalJoint joint)
+        {
+            Vector3 anchorA = GetAnchor(joint, JointBody.A);
+            Vector3 anchorB = GetAnchor(joint, JointBody.B);
+
+            Gizmos.Color = Color.White;
+            Gizmos.DrawSphere(anchorA, 0.05f);
+            Gizmos.DrawSphere(anchorB, 0.05f);
+
+            Gizmos.Color = Color.Green;
+            if (joint.EnableLimit)
+            {
+                LimitConeRange limit = joint.Limit;
+
+                Vector2 scale;
+                scale.x = MathEx.Cos(limit.ZLimitAngle * 0.5f);
+                scale.y = MathEx.Cos(limit.YLimitAngle * 0.5f);
+
+                Gizmos.Transform = joint.SceneObject.WorldTransform;
+                Gizmos.DrawCone(Vector3.Zero, Vector3.XAxis, 1.0f, 1.0f, scale);
+            }
+            else
+            {
+                Gizmos.DrawWireSphere(joint.SceneObject.Position, 1.0f);
+            }
+        }
+
+        /// <summary>
+        /// Method called by the runtime when joints are meant to be drawn.
+        /// </summary>
+        /// <param name="joint">Joint to draw gizmos for.</param>
+        [DrawGizmo(DrawGizmoFlags.Selected | DrawGizmoFlags.ParentSelected)]
+        private static void DrawHingeJoint(HingeJoint joint)
+        {
+            Vector3 anchorA = GetAnchor(joint, JointBody.A);
+            Vector3 anchorB = GetAnchor(joint, JointBody.B);
+
+            Gizmos.Color = Color.White;
+            Gizmos.DrawSphere(anchorA, 0.05f);
+            Gizmos.DrawSphere(anchorB, 0.05f);
+
+            if (joint.EnableLimit)
+            {
+                Gizmos.Transform = joint.SceneObject.WorldTransform;
+
+                LimitAngularRange limit = joint.Limit;
+
+                Action<float> drawLimitedArc = x =>
+                {
+                    // Arc zero to lower limit
+                    Gizmos.Color = Color.Red;
+                    Gizmos.DrawWireArc(Vector3.XAxis * x, Vector3.XAxis, 0.25f, -limit.Lower * 0.5f, limit.Lower);
+
+                    // Arc lower to upper limit
+                    Degree validRange = limit.Upper - limit.Lower;
+
+                    Gizmos.Color = Color.Green;
+                    Gizmos.DrawWireArc(Vector3.XAxis * x, Vector3.XAxis, 0.25f, -limit.Lower - validRange * 0.5f, validRange * 0.5f);
+                    Gizmos.DrawWireArc(Vector3.XAxis * x, Vector3.XAxis, 0.25f, limit.Lower * 0.5f, validRange * 0.5f);
+
+                    // Arc upper to full circle
+                    Degree remainingRange = new Degree(360) - MathEx.WrapAngle(limit.Upper);
+
+                    Gizmos.DrawWireArc(Vector3.XAxis * x, Vector3.XAxis, 0.25f, -limit.Upper - remainingRange * 0.5f, remainingRange * 0.5f);
+                    Gizmos.DrawWireArc(Vector3.XAxis * x, Vector3.XAxis, 0.25f, limit.Upper * 0.5f, remainingRange * 0.5f);
+                };
+
+                drawLimitedArc(-0.5f);
+                drawLimitedArc(0.5f);
+            }
+            else
+            {
+                Gizmos.Color = Color.Green;
+                Gizmos.Transform = joint.SceneObject.WorldTransform;
+
+                Gizmos.DrawWireDisc(Vector3.XAxis * -0.5f, Vector3.XAxis, 0.25f);
+                Gizmos.DrawWireDisc(Vector3.XAxis * 0.5f, Vector3.XAxis, 0.25f);
+            }
+
+            Vector3[] lineStartPoints = new Vector3[4];
+            lineStartPoints[0] = new Vector3(-0.5f, 0.25f, 0.25f);
+            lineStartPoints[1] = new Vector3(-0.5f, 0.25f, -0.25f);
+            lineStartPoints[2] = new Vector3(-0.5f, -0.25f, 0.25f);
+            lineStartPoints[3] = new Vector3(-0.5f, -0.25f, -0.25f);
+
+            Vector3[] lineEndPoints = new Vector3[4];
+            lineEndPoints[0] = new Vector3(0.5f, 0.25f, 0.25f);
+            lineEndPoints[1] = new Vector3(0.5f, 0.25f, -0.25f);
+            lineEndPoints[2] = new Vector3(0.5f, -0.25f, 0.25f);
+            lineEndPoints[3] = new Vector3(0.5f, -0.25f, -0.25f);
+
+            for (int i = 0; i < 4; i++)
+                Gizmos.DrawLine(lineStartPoints[i], lineEndPoints[i]);
+        }
+
+        /// <summary>
+        /// Method called by the runtime when joints are meant to be drawn.
+        /// </summary>
+        /// <param name="joint">Joint to draw gizmos for.</param>
+        [DrawGizmo(DrawGizmoFlags.Selected | DrawGizmoFlags.ParentSelected)]
+        private static void DrawD6Joint(D6Joint joint)
+        {
+            Vector3 anchorA = GetAnchor(joint, JointBody.A);
+            Vector3 anchorB = GetAnchor(joint, JointBody.B);
+
+            Gizmos.Color = Color.White;
+            Gizmos.DrawSphere(anchorA, 0.05f);
+            Gizmos.DrawSphere(anchorB, 0.05f);
+        }
     }
-}
+}

+ 4 - 2
Source/MBansheeEngine/Physics/Joint.cs

@@ -301,8 +301,10 @@ namespace BansheeEngine
 		    Rigidbody rigidbody = serializableData.bodies[(int)body];
 		    if (rigidbody != null)
 		    {
-			    localRot = rigidbody.SceneObject.Rotation * localRot;
-			    localPos = localRot.Rotate(localPos) + rigidbody.SceneObject.Position;
+		        Quaternion worldRot = rigidbody.SceneObject.Rotation;
+
+			    localRot = worldRot * localRot;
+			    localPos = worldRot.Rotate(localPos) + rigidbody.SceneObject.Position;
 		    }
 
 		    // Transform to space local to the joint

+ 2 - 0
Source/SBansheeEditor/Include/BsScriptGizmos.h

@@ -30,9 +30,11 @@ namespace BansheeEngine
 		static void internal_GetTransform(Matrix4* transform);
 		static void internal_DrawCube(Vector3* position, Vector3* extents);
 		static void internal_DrawSphere(Vector3* position, float radius);
+		static void internal_DrawCone(Vector3* base, Vector3* normal, float height, float radius, Vector2* scale);
 		static void internal_DrawWireCube(Vector3* position, Vector3* extents);
 		static void internal_DrawWireSphere(Vector3* position, float radius);
 		static void internal_DrawWireCapsule(Vector3* position, float height, float radius);
+		static void internal_DrawWireCone(Vector3* base, Vector3* normal, float height, float radius, Vector2* scale);
 		static void internal_DrawLine(Vector3* start, Vector3* end);
 		static void internal_DrawLineList(MonoArray* linePoints);
 		static void internal_DrawWireDisc(Vector3* position, Vector3* normal, float radius);

+ 12 - 0
Source/SBansheeEditor/Source/BsScriptGizmos.cpp

@@ -19,9 +19,11 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_GetTransform", &ScriptGizmos::internal_GetTransform);
 		metaData.scriptClass->addInternalCall("Internal_DrawCube", &ScriptGizmos::internal_DrawCube);
 		metaData.scriptClass->addInternalCall("Internal_DrawSphere", &ScriptGizmos::internal_DrawSphere);
+		metaData.scriptClass->addInternalCall("Internal_DrawCone", &ScriptGizmos::internal_DrawCone);
 		metaData.scriptClass->addInternalCall("Internal_DrawWireCube", &ScriptGizmos::internal_DrawWireCube);
 		metaData.scriptClass->addInternalCall("Internal_DrawWireSphere", &ScriptGizmos::internal_DrawWireSphere);
 		metaData.scriptClass->addInternalCall("Internal_DrawWireCapsule", &ScriptGizmos::internal_DrawWireCapsule);
+		metaData.scriptClass->addInternalCall("Internal_DrawWireCone", &ScriptGizmos::internal_DrawWireCone);
 		metaData.scriptClass->addInternalCall("Internal_DrawWireDisc", &ScriptGizmos::internal_DrawWireDisc);
 		metaData.scriptClass->addInternalCall("Internal_DrawWireArc", &ScriptGizmos::internal_DrawWireArc);
 		metaData.scriptClass->addInternalCall("Internal_DrawWireMesh", &ScriptGizmos::internal_DrawWireMesh);
@@ -62,6 +64,11 @@ namespace BansheeEngine
 		GizmoManager::instance().drawSphere(*position, radius);
 	}
 
+	void ScriptGizmos::internal_DrawCone(Vector3* base, Vector3* normal, float height, float radius, Vector2* scale)
+	{
+		GizmoManager::instance().drawCone(*base, *normal, height, radius, *scale);
+	}
+
 	void ScriptGizmos::internal_DrawWireCube(Vector3* position, Vector3* extents)
 	{
 		GizmoManager::instance().drawWireCube(*position, *extents);
@@ -77,6 +84,11 @@ namespace BansheeEngine
 		GizmoManager::instance().drawWireCapsule(*position, height, radius);
 	}
 
+	void ScriptGizmos::internal_DrawWireCone(Vector3* base, Vector3* normal, float height, float radius, Vector2* scale)
+	{
+		GizmoManager::instance().drawWireCone(*base, *normal, height, radius, *scale);
+	}
+
 	void ScriptGizmos::internal_DrawLine(Vector3* start, Vector3* end)
 	{
 		GizmoManager::instance().drawLine(*start, *end);