summaryrefslogtreecommitdiff
path: root/Runtime/Filters/Misc/LineRenderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Runtime/Filters/Misc/LineRenderer.cpp')
-rw-r--r--Runtime/Filters/Misc/LineRenderer.cpp195
1 files changed, 195 insertions, 0 deletions
diff --git a/Runtime/Filters/Misc/LineRenderer.cpp b/Runtime/Filters/Misc/LineRenderer.cpp
new file mode 100644
index 0000000..1bab153
--- /dev/null
+++ b/Runtime/Filters/Misc/LineRenderer.cpp
@@ -0,0 +1,195 @@
+#include "UnityPrefix.h"
+#include "LineRenderer.h"
+#include "Runtime/Mono/MonoManager.h"
+#include "Runtime/Graphics/Transform.h"
+#include "Runtime/Serialize/TransferFunctions/SerializeTransfer.h"
+#include "Runtime/Serialize/TransferFunctions/TransferNameConversions.h"
+#include "Runtime/Camera/RenderManager.h"
+#include "Runtime/Camera/Camera.h"
+#include "Runtime/Shaders/VBO.h"
+#include "Runtime/GfxDevice/GfxDevice.h"
+#include "Runtime/Profiler/Profiler.h"
+
+IMPLEMENT_CLASS_INIT_ONLY (LineRenderer)
+IMPLEMENT_OBJECT_SERIALIZE (LineRenderer)
+
+LineRenderer::LineRenderer (MemLabelId label, ObjectCreationMode mode)
+: Super(kRendererLine, label, mode)
+{
+ SetVisible (false);
+}
+
+LineRenderer::~LineRenderer ()
+{
+}
+
+void LineRenderer::InitializeClass ()
+{
+ RegisterAllowNameConversion (LineRenderer::GetClassStringStatic(), "m_WorldSpace", "m_UseWorldSpace");
+}
+
+
+void LineRenderer::SetVertexCount(int count)
+{
+ if(count < 0)
+ {
+ count = 0;
+ ErrorString ("LineRenderer.SetVertexCount: Vertex count can't be set to negative value!");
+ }
+ UpdateManagerState( true );
+ m_Positions.resize(count);
+ SetVisible (m_Positions.size() >= 2);
+ SetDirty();
+ BoundsChanged();
+}
+
+void LineRenderer::AwakeFromLoad(AwakeFromLoadMode awakeMode)
+{
+ Super::AwakeFromLoad(awakeMode);
+ SetVisible (m_Positions.size() >= 2);
+
+ if ((awakeMode & kDidLoadFromDisk) == 0)
+ BoundsChanged();
+}
+
+void LineRenderer::SetPosition (int index, const Vector3f& position)
+{
+ SetDirty();
+ UpdateManagerState( true );
+ if (index < m_Positions.size() && index >= 0)
+ m_Positions[index] = position;
+ else
+ ErrorString("LineRenderer.SetPosition index out of bounds!");
+ BoundsChanged();
+}
+
+PROFILER_INFORMATION(gSubmitVBOProfileLine, "Mesh.SubmitVBO", kProfilerRender)
+
+
+void LineRenderer::Render (int subsetIndex, const ChannelAssigns& channels)
+{
+ if( m_Positions.size() < 2 )
+ return;
+
+ Vector3f* lineInVerts = NULL;
+ ALLOC_TEMP(lineInVerts, Vector3f, m_Positions.size());
+
+ MinMaxAABB mmAABB = MinMaxAABB(Vector3f::zero, Vector3f::zero);
+
+ if (m_UseWorldSpace)
+ {
+ memcpy (lineInVerts, &m_Positions[0], m_Positions.size()*sizeof(Vector3f));
+ }
+ else
+ {
+ Transform& tc = GetComponent(Transform);
+ int idx = 0;
+ for (PositionVector::iterator j = m_Positions.begin(); j != m_Positions.end(); ++j, ++idx)
+ {
+ lineInVerts[idx] = tc.TransformPoint(*j);
+ }
+ }
+
+ // Get VBO chunk
+ int stripCount = m_Positions.size() * 2;
+ GfxDevice& device = GetGfxDevice();
+ DynamicVBO& vbo = device.GetDynamicVBO();
+ LineVertex* vbPtr;
+ if( !vbo.GetChunk( (1<<kShaderChannelVertex) | (1<<kShaderChannelTexCoord0) | (1<<kShaderChannelColor),
+ stripCount, 0,
+ DynamicVBO::kDrawTriangleStrip,
+ (void**)&vbPtr, NULL ) )
+ {
+ return;
+ }
+
+ // Generate line into the chunk
+ m_Parameters.outVertices = vbPtr;
+ m_Parameters.outAABB = &mmAABB;
+ m_Parameters.cameraTransform = GetCurrentCamera().GetWorldToCameraMatrix();
+ Build3DLine (&m_Parameters, lineInVerts, m_Positions.size());
+
+ vbo.ReleaseChunk( stripCount, 0 );
+
+ // We can't set the view matrix since that breaks shadow maps (case 490315)
+ // Set the world matrix instead so it cancels out the usual view matrix
+ // i.e. it transforms from camera space back to world space
+ device.SetWorldMatrix(GetCurrentCamera().GetCameraToWorldMatrix().GetPtr());
+
+ if (m_CustomProperties)
+ device.SetMaterialProperties (*m_CustomProperties);
+
+ PROFILER_BEGIN(gSubmitVBOProfileLine, this)
+ vbo.DrawChunk (channels);
+ GPU_TIMESTAMP();
+ PROFILER_END
+}
+
+void LineRenderer::UpdateTransformInfo ()
+{
+ const Transform& transform = GetTransform();
+ if (m_TransformDirty)
+ {
+ m_TransformInfo.invScale = 1.0f;
+ // will return a cached matrix most of the time
+ m_TransformInfo.transformType = transform.CalculateTransformMatrix (m_TransformInfo.worldMatrix);;
+ }
+
+ if (m_BoundsDirty)
+ {
+ MinMaxAABB minmax;
+ minmax.Init();
+ for (PositionVector::const_iterator i = m_Positions.begin(), itEnd = m_Positions.end(); i != itEnd; ++i)
+ minmax.Encapsulate (*i);
+
+ if (m_UseWorldSpace)
+ {
+ m_TransformInfo.worldAABB = minmax;
+ TransformAABB (m_TransformInfo.worldAABB, transform.GetWorldToLocalMatrix(), m_TransformInfo.localAABB);
+ }
+ else
+ {
+ m_TransformInfo.localAABB = minmax;
+ TransformAABB (m_TransformInfo.localAABB, transform.GetLocalToWorldMatrix(), m_TransformInfo.worldAABB);
+ }
+ }
+}
+
+
+
+void LineRenderer::UpdateRenderer()
+{
+ Super::UpdateRenderer();
+ if (m_BoundsDirty)
+ {
+ BoundsChanged();
+ }
+}
+
+void LineRenderer::Reset()
+{
+ Super::Reset();
+ m_UseWorldSpace = true;
+ m_Positions.clear();
+ m_Positions.push_back (Vector3f (0,0,0));
+ m_Positions.push_back (Vector3f (0,0,1));
+ m_Parameters.color1 = ColorRGBA32(255, 255, 255, 255);
+ m_Parameters.color2 = ColorRGBA32(255, 255, 255, 255);
+ SetVisible (true);
+}
+
+void LineRenderer::SetUseWorldSpace (bool space)
+{
+ m_UseWorldSpace = space;
+ SetDirty();
+ UpdateManagerState( true );
+ BoundsChanged();
+}
+
+template<class TransferFunction> inline
+void LineRenderer::Transfer (TransferFunction& transfer) {
+ Super::Transfer (transfer);
+ TRANSFER_SIMPLE (m_Positions);
+ TRANSFER_SIMPLE (m_Parameters);
+ TRANSFER (m_UseWorldSpace);
+}