소스 검색

Renderer: Add gizmos drawing

Panagiotis Christopoulos Charitos 3 주 전
부모
커밋
3904e6d9af
4개의 변경된 파일335개의 추가작업 그리고 1개의 파일을 삭제
  1. 13 0
      AnKi/Editor/EditorUi.cpp
  2. 267 0
      AnKi/Renderer/Dbg.cpp
  3. 24 0
      AnKi/Renderer/Dbg.h
  4. 31 1
      AnKi/Shaders/Dbg.ankiprog

+ 13 - 0
AnKi/Editor/EditorUi.cpp

@@ -1551,6 +1551,19 @@ void EditorUi::selectSceneNode()
 				return FunctorContinue::kContinue;
 			});
 		}
+		else
+		{
+			m_sceneHierarchyWindow.m_selectedNode = nullptr;
+		}
+	}
+
+	if(m_sceneHierarchyWindow.m_selectedNode)
+	{
+		Renderer::getSingleton().getDbg().setGizmosTransform(m_sceneHierarchyWindow.m_selectedNode->getWorldTransform(), true);
+	}
+	else
+	{
+		Renderer::getSingleton().getDbg().setGizmosTransform(Transform::getIdentity(), false);
 	}
 }
 

+ 267 - 0
AnKi/Renderer/Dbg.cpp

@@ -24,6 +24,186 @@
 
 namespace anki {
 
+static const F32 g_gizmoArrowPositions[49][3] = {{0.035852f, -0.0f, -0.0f},
+												 {0.035852f, -0.0f, 0.752929f},
+												 {0.033123f, -0.01372f, -0.0f},
+												 {0.033123f, -0.01372f, 0.752929f},
+												 {0.025351f, -0.025351f, -0.0f},
+												 {0.025351f, -0.025351f, 0.752929f},
+												 {0.01372f, -0.033123f, -0.0f},
+												 {0.01372f, -0.033123f, 0.752929f},
+												 {0.0f, -0.035852f, -0.0f},
+												 {-0.0f, -0.035852f, 0.752929f},
+												 {-0.01372f, -0.033123f, -0.0f},
+												 {-0.01372f, -0.033123f, 0.752929f},
+												 {-0.025351f, -0.025351f, -0.0f},
+												 {-0.025351f, -0.025351f, 0.752929f},
+												 {-0.033123f, -0.01372f, -0.0f},
+												 {-0.033123f, -0.01372f, 0.752929f},
+												 {-0.035852f, -0.0f, -0.0f},
+												 {-0.035852f, -0.0f, 0.752929f},
+												 {-0.033123f, 0.01372f, -0.0f},
+												 {-0.033123f, 0.01372f, 0.752929f},
+												 {-0.025351f, 0.025351f, -0.0f},
+												 {-0.025351f, 0.025351f, 0.752929f},
+												 {-0.01372f, 0.033123f, -0.0f},
+												 {-0.01372f, 0.033123f, 0.752929f},
+												 {0.0f, 0.035852f, -0.0f},
+												 {-0.0f, 0.035852f, 0.752929f},
+												 {0.01372f, 0.033123f, -0.0f},
+												 {0.01372f, 0.033123f, 0.752929f},
+												 {0.025351f, 0.025351f, -0.0f},
+												 {0.025351f, 0.025351f, 0.752929f},
+												 {0.033123f, 0.01372f, -0.0f},
+												 {0.033123f, 0.01372f, 0.752929f},
+												 {0.072426f, -0.0f, 0.778954f},
+												 {0.066913f, -0.027717f, 0.778954f},
+												 {0.051213f, -0.051213f, 0.778954f},
+												 {0.027716f, -0.066913f, 0.778954f},
+												 {-0.0f, -0.072427f, 0.778954f},
+												 {-0.027716f, -0.066913f, 0.778954f},
+												 {-0.051213f, -0.051213f, 0.778954f},
+												 {-0.066913f, -0.027717f, 0.778954f},
+												 {-0.072426f, -0.0f, 0.778954f},
+												 {-0.066913f, 0.027716f, 0.778954f},
+												 {-0.051213f, 0.051213f, 0.778954f},
+												 {-0.027716f, 0.066913f, 0.778954f},
+												 {-0.0f, 0.072426f, 0.778954f},
+												 {0.027716f, 0.066913f, 0.778954f},
+												 {0.051213f, 0.051213f, 0.778954f},
+												 {0.066913f, 0.027716f, 0.778954f},
+												 {-0.0f, -0.0f, 1.0f}};
+
+static const U16 g_gizmoArrowIndices[94][3] = {
+	{1, 2, 0},    {3, 4, 2},    {5, 6, 4},    {6, 9, 8},    {9, 10, 8},   {11, 12, 10}, {13, 14, 12}, {15, 16, 14}, {17, 18, 16}, {19, 20, 18},
+	{21, 22, 20}, {23, 24, 22}, {25, 26, 24}, {27, 28, 26}, {13, 37, 38}, {29, 30, 28}, {31, 0, 30},  {6, 14, 22},  {46, 45, 48}, {23, 42, 43},
+	{1, 47, 32},  {7, 36, 9},   {19, 40, 41}, {27, 46, 29}, {5, 33, 34},  {15, 38, 39}, {23, 44, 25}, {9, 37, 11},  {19, 42, 21}, {29, 47, 31},
+	{7, 34, 35},  {15, 40, 17}, {1, 33, 3},   {25, 45, 27}, {39, 38, 48}, {47, 46, 48}, {40, 39, 48}, {33, 32, 48}, {32, 47, 48}, {41, 40, 48},
+	{34, 33, 48}, {42, 41, 48}, {35, 34, 48}, {43, 42, 48}, {36, 35, 48}, {44, 43, 48}, {37, 36, 48}, {45, 44, 48}, {38, 37, 48}, {1, 3, 2},
+	{3, 5, 4},    {5, 7, 6},    {6, 7, 9},    {9, 11, 10},  {11, 13, 12}, {13, 15, 14}, {15, 17, 16}, {17, 19, 18}, {19, 21, 20}, {21, 23, 22},
+	{23, 25, 24}, {25, 27, 26}, {27, 29, 28}, {13, 11, 37}, {29, 31, 30}, {31, 1, 0},   {30, 0, 2},   {2, 4, 6},    {6, 8, 10},   {10, 12, 14},
+	{14, 16, 22}, {16, 18, 22}, {18, 20, 22}, {22, 24, 26}, {26, 28, 22}, {28, 30, 22}, {30, 2, 6},   {6, 10, 14},  {30, 6, 22},  {23, 21, 42},
+	{1, 31, 47},  {7, 35, 36},  {19, 17, 40}, {27, 45, 46}, {5, 3, 33},   {15, 13, 38}, {23, 43, 44}, {9, 36, 37},  {19, 41, 42}, {29, 46, 47},
+	{7, 5, 34},   {15, 39, 40}, {1, 32, 33},  {25, 44, 45}};
+
+static const F32 g_gizmoScalePositions[64][3] = {
+	{0.035852f, -0.0f, -0.0f},       {0.035852f, -0.0f, 0.752929f},       {0.033123f, -0.01372f, -0.0f},       {0.033123f, -0.01372f, 0.752929f},
+	{0.025351f, -0.025351f, -0.0f},  {0.025351f, -0.025351f, 0.752929f},  {0.01372f, -0.033123f, -0.0f},       {0.01372f, -0.033123f, 0.752929f},
+	{0.0f, -0.035852f, -0.0f},       {-0.0f, -0.035852f, 0.752929f},      {-0.01372f, -0.033123f, -0.0f},      {-0.01372f, -0.033123f, 0.752929f},
+	{-0.025351f, -0.025351f, -0.0f}, {-0.025351f, -0.025351f, 0.752929f}, {-0.033123f, -0.01372f, -0.0f},      {-0.033123f, -0.01372f, 0.752929f},
+	{-0.035852f, -0.0f, -0.0f},      {-0.035852f, -0.0f, 0.752929f},      {-0.033123f, 0.01372f, -0.0f},       {-0.033123f, 0.01372f, 0.752929f},
+	{-0.025351f, 0.025351f, -0.0f},  {-0.025351f, 0.025351f, 0.752929f},  {-0.01372f, 0.033123f, -0.0f},       {-0.01372f, 0.033123f, 0.752929f},
+	{0.0f, 0.035852f, -0.0f},        {-0.0f, 0.035852f, 0.752929f},       {0.01372f, 0.033123f, -0.0f},        {0.01372f, 0.033123f, 0.752929f},
+	{0.025351f, 0.025351f, -0.0f},   {0.025351f, 0.025351f, 0.752929f},   {0.033123f, 0.01372f, -0.0f},        {0.033123f, 0.01372f, 0.752929f},
+	{0.072426f, -0.0f, 0.778954f},   {0.066913f, -0.027717f, 0.778954f},  {0.051213f, -0.051213f, 0.778954f},  {0.027716f, -0.066913f, 0.778954f},
+	{-0.0f, -0.072427f, 0.778954f},  {-0.027716f, -0.066913f, 0.778954f}, {-0.051213f, -0.051213f, 0.778954f}, {-0.066913f, -0.027717f, 0.778954f},
+	{-0.072426f, -0.0f, 0.778954f},  {-0.066913f, 0.027716f, 0.778954f},  {-0.051213f, 0.051213f, 0.778954f},  {-0.027716f, 0.066913f, 0.778954f},
+	{-0.0f, 0.072426f, 0.778954f},   {0.027716f, 0.066913f, 0.778954f},   {0.051213f, 0.051213f, 0.778954f},   {0.066913f, 0.027716f, 0.778954f},
+	{0.072426f, -0.0f, 0.998954f},   {0.066913f, -0.027717f, 0.998954f},  {0.051213f, -0.051213f, 0.998954f},  {0.027716f, -0.066913f, 0.998954f},
+	{-0.0f, -0.072427f, 0.998954f},  {-0.027716f, -0.066913f, 0.998954f}, {-0.051213f, -0.051213f, 0.998954f}, {-0.066913f, -0.027717f, 0.998954f},
+	{-0.072426f, -0.0f, 0.998954f},  {-0.066913f, 0.027716f, 0.998954f},  {-0.051213f, 0.051213f, 0.998954f},  {-0.027716f, 0.066913f, 0.998954f},
+	{-0.0f, 0.072426f, 0.998954f},   {0.027716f, 0.066913f, 0.998954f},   {0.051213f, 0.051213f, 0.998954f},   {0.066913f, 0.027716f, 0.998954f},
+};
+
+static const U16 g_gizmoScaleIndices[124][3] = {
+	{1, 2, 0},    {3, 4, 2},    {5, 6, 4},    {6, 9, 8},    {9, 10, 8},   {11, 12, 10}, {13, 14, 12}, {15, 16, 14}, {17, 18, 16}, {19, 20, 18},
+	{21, 22, 20}, {23, 24, 22}, {25, 26, 24}, {27, 28, 26}, {13, 37, 38}, {29, 30, 28}, {31, 0, 30},  {6, 14, 22},  {39, 56, 40}, {23, 42, 43},
+	{1, 47, 32},  {7, 36, 9},   {19, 40, 41}, {27, 46, 29}, {5, 33, 34},  {15, 38, 39}, {23, 44, 25}, {9, 37, 11},  {19, 42, 21}, {29, 47, 31},
+	{7, 34, 35},  {15, 40, 17}, {1, 33, 3},   {25, 45, 27}, {45, 62, 46}, {47, 62, 63}, {38, 53, 54}, {43, 60, 44}, {44, 61, 45}, {36, 53, 37},
+	{35, 52, 36}, {42, 59, 43}, {47, 48, 32}, {34, 51, 35}, {40, 57, 41}, {41, 58, 42}, {34, 49, 50}, {32, 49, 33}, {38, 55, 39}, {57, 53, 49},
+	{1, 3, 2},    {3, 5, 4},    {5, 7, 6},    {6, 7, 9},    {9, 11, 10},  {11, 13, 12}, {13, 15, 14}, {15, 17, 16}, {17, 19, 18}, {19, 21, 20},
+	{21, 23, 22}, {23, 25, 24}, {25, 27, 26}, {27, 29, 28}, {13, 11, 37}, {29, 31, 30}, {31, 1, 0},   {30, 0, 2},   {2, 4, 6},    {6, 8, 10},
+	{10, 12, 14}, {14, 16, 22}, {16, 18, 22}, {18, 20, 22}, {22, 24, 26}, {26, 28, 22}, {28, 30, 22}, {30, 2, 6},   {6, 10, 14},  {30, 6, 22},
+	{39, 55, 56}, {23, 21, 42}, {1, 31, 47},  {7, 35, 36},  {19, 17, 40}, {27, 45, 46}, {5, 3, 33},   {15, 13, 38}, {23, 43, 44}, {9, 36, 37},
+	{19, 41, 42}, {29, 46, 47}, {7, 5, 34},   {15, 39, 40}, {1, 32, 33},  {25, 44, 45}, {45, 61, 62}, {47, 46, 62}, {38, 37, 53}, {43, 59, 60},
+	{44, 60, 61}, {36, 52, 53}, {35, 51, 52}, {42, 58, 59}, {47, 63, 48}, {34, 50, 51}, {40, 56, 57}, {41, 57, 58}, {34, 33, 49}, {32, 48, 49},
+	{38, 54, 55}, {49, 48, 63}, {63, 62, 61}, {61, 60, 59}, {59, 58, 61}, {58, 57, 61}, {57, 56, 53}, {56, 55, 53}, {55, 54, 53}, {53, 52, 49},
+	{52, 51, 49}, {51, 50, 49}, {49, 63, 61}, {49, 61, 57},
+};
+
+static const F32 g_gizmoRingPositions[64][3] = {
+	{0.0f, 1.0f, -0.008517f},
+	{0.0f, 1.0f, 0.008517f},
+	{0.382683f, 0.92388f, -0.008517f},
+	{0.382683f, 0.92388f, 0.008517f},
+	{0.707107f, 0.707107f, -0.008517f},
+	{0.707107f, 0.707107f, 0.008517f},
+	{0.923879f, 0.382683f, -0.008517f},
+	{0.923879f, 0.382683f, 0.008517f},
+	{1.0f, 0.0f, -0.008517f},
+	{1.0f, 0.0f, 0.008517f},
+	{0.923879f, -0.382683f, -0.008517f},
+	{0.923879f, -0.382683f, 0.008517f},
+	{0.707107f, -0.707107f, -0.008517f},
+	{0.707107f, -0.707107f, 0.008517f},
+	{0.382683f, -0.92388f, -0.008517f},
+	{0.382683f, -0.92388f, 0.008517f},
+	{0.0f, -1.0f, -0.008517f},
+	{0.0f, -1.0f, 0.008517f},
+	{-0.382683f, -0.92388f, -0.008517f},
+	{-0.382683f, -0.92388f, 0.008517f},
+	{-0.707107f, -0.707107f, -0.008517f},
+	{-0.707107f, -0.707107f, 0.008517f},
+	{-0.923879f, -0.382683f, -0.008517f},
+	{-0.923879f, -0.382683f, 0.008517f},
+	{-1.0f, 0.0f, -0.008517f},
+	{-1.0f, 0.0f, 0.008517f},
+	{-0.923879f, 0.382683f, -0.008517f},
+	{-0.923879f, 0.382683f, 0.008517f},
+	{-0.707107f, 0.707107f, -0.008517f},
+	{-0.707107f, 0.707107f, 0.008517f},
+	{-0.382683f, 0.92388f, -0.008517f},
+	{-0.382683f, 0.92388f, 0.008517f},
+	{-0.0f, 0.914026f, 0.011446f},
+	{0.349782f, 0.84445f, 0.011446f},
+	{0.646314f, 0.646314f, 0.011446f},
+	{0.844449f, 0.349783f, 0.011446f},
+	{0.914025f, 0.0f, 0.011446f},
+	{0.844449f, -0.349782f, 0.011446f},
+	{0.646314f, -0.646314f, 0.011446f},
+	{0.349782f, -0.844449f, 0.011446f},
+	{-0.0f, -0.914025f, 0.011446f},
+	{-0.349782f, -0.844449f, 0.011446f},
+	{-0.646314f, -0.646314f, 0.011446f},
+	{-0.844449f, -0.349782f, 0.011446f},
+	{-0.914025f, 0.0f, 0.011446f},
+	{-0.844449f, 0.349783f, 0.011446f},
+	{-0.646314f, 0.646314f, 0.011446f},
+	{-0.349782f, 0.84445f, 0.011446f},
+	{0.0f, 0.914026f, -0.011446f},
+	{0.349783f, 0.84445f, -0.011446f},
+	{0.646314f, 0.646314f, -0.011446f},
+	{0.84445f, 0.349783f, -0.011446f},
+	{0.914026f, 0.0f, -0.011446f},
+	{0.84445f, -0.349782f, -0.011446f},
+	{0.646314f, -0.646314f, -0.011446f},
+	{0.349783f, -0.844449f, -0.011446f},
+	{0.0f, -0.914025f, -0.011446f},
+	{-0.349782f, -0.844449f, -0.011446f},
+	{-0.646313f, -0.646314f, -0.011446f},
+	{-0.844449f, -0.349782f, -0.011446f},
+	{-0.914025f, 0.0f, -0.011446f},
+	{-0.844449f, 0.349783f, -0.011446f},
+	{-0.646313f, 0.646314f, -0.011446f},
+	{-0.349782f, 0.84445f, -0.011446f},
+};
+
+static const U16 g_gizmoRingIndices[128][3] = {
+	{0, 3, 2},    {3, 4, 2},    {5, 6, 4},    {7, 8, 6},    {9, 10, 8},   {11, 12, 10}, {13, 14, 12}, {15, 16, 14}, {17, 18, 16}, {19, 20, 18},
+	{21, 22, 20}, {23, 24, 22}, {25, 26, 24}, {27, 28, 26}, {23, 42, 43}, {29, 30, 28}, {31, 0, 30},  {41, 58, 42}, {31, 32, 1},  {7, 36, 9},
+	{19, 40, 41}, {29, 45, 46}, {3, 34, 5},   {13, 39, 15}, {25, 43, 44}, {9, 37, 11},  {21, 41, 42}, {31, 46, 47}, {5, 35, 7},   {17, 39, 40},
+	{1, 33, 3},   {27, 44, 45}, {11, 38, 13}, {6, 52, 51},  {35, 50, 51}, {42, 59, 43}, {36, 51, 52}, {43, 60, 44}, {36, 53, 37}, {45, 60, 61},
+	{37, 54, 38}, {46, 61, 62}, {38, 55, 39}, {47, 62, 63}, {39, 56, 40}, {33, 48, 49}, {32, 63, 48}, {40, 57, 41}, {34, 49, 50}, {8, 53, 52},
+	{10, 54, 53}, {12, 55, 54}, {14, 56, 55}, {16, 57, 56}, {18, 58, 57}, {22, 58, 20}, {24, 59, 22}, {26, 60, 24}, {28, 61, 26}, {30, 62, 28},
+	{0, 63, 30},  {2, 48, 0},   {4, 49, 2},   {6, 50, 4},   {0, 1, 3},    {3, 5, 4},    {5, 7, 6},    {7, 9, 8},    {9, 11, 10},  {11, 13, 12},
+	{13, 15, 14}, {15, 17, 16}, {17, 19, 18}, {19, 21, 20}, {21, 23, 22}, {23, 25, 24}, {25, 27, 26}, {27, 29, 28}, {23, 21, 42}, {29, 31, 30},
+	{31, 1, 0},   {41, 57, 58}, {31, 47, 32}, {7, 35, 36},  {19, 17, 40}, {29, 27, 45}, {3, 33, 34},  {13, 38, 39}, {25, 23, 43}, {9, 36, 37},
+	{21, 19, 41}, {31, 29, 46}, {5, 34, 35},  {17, 15, 39}, {1, 32, 33},  {27, 25, 44}, {11, 37, 38}, {6, 8, 52},   {35, 34, 50}, {42, 58, 59},
+	{36, 35, 51}, {43, 59, 60}, {36, 52, 53}, {45, 44, 60}, {37, 53, 54}, {46, 45, 61}, {38, 54, 55}, {47, 46, 62}, {39, 55, 56}, {33, 32, 48},
+	{32, 47, 63}, {40, 56, 57}, {34, 33, 49}, {8, 10, 53},  {10, 12, 54}, {12, 14, 55}, {14, 16, 56}, {16, 18, 57}, {18, 20, 58}, {22, 59, 58},
+	{24, 60, 59}, {26, 61, 60}, {28, 62, 61}, {30, 63, 62}, {0, 48, 63},  {2, 49, 48},  {4, 50, 49},  {6, 51, 50},
+};
+
 Dbg::Dbg()
 {
 }
@@ -117,9 +297,46 @@ Error Dbg::init()
 		ANKI_ASSERT(c == kIndexCount);
 	}
 
+	initGizmos();
+
 	return Error::kNone;
 }
 
+void Dbg::initGizmos()
+{
+	auto createPair = [](CString name, ConstWeakArray<F32> positionsArray, ConstWeakArray<U16> indicesArray, BufferPtr& positionsBuff,
+						 BufferPtr& indicesBuff) {
+		BufferInitInfo buffInit(name);
+		buffInit.m_mapAccess = BufferMapAccessBit::kWrite;
+		buffInit.m_size = positionsArray.getSizeInBytes();
+		buffInit.m_usage = BufferUsageBit::kVertexOrIndex;
+		positionsBuff = GrManager::getSingleton().newBuffer(buffInit);
+
+		void* mapped = positionsBuff->map(0, kMaxPtrSize, BufferMapAccessBit::kWrite);
+		memcpy(mapped, positionsArray.getBegin(), positionsArray.getSizeInBytes());
+		positionsBuff->unmap();
+
+		buffInit.m_size = indicesArray.getSizeInBytes();
+		indicesBuff = GrManager::getSingleton().newBuffer(buffInit);
+
+		mapped = indicesBuff->map(0, kMaxPtrSize, BufferMapAccessBit::kWrite);
+		memcpy(mapped, indicesArray.getBegin(), indicesArray.getSizeInBytes());
+		indicesBuff->unmap();
+	};
+
+	createPair("GizmosArrow", ConstWeakArray<F32>(&g_gizmoArrowPositions[0][0], sizeof(g_gizmoArrowPositions) / sizeof(F32)),
+			   ConstWeakArray<U16>(&g_gizmoArrowIndices[0][0], sizeof(g_gizmoArrowIndices) / sizeof(U16)), m_gizmos.m_arrowPositions,
+			   m_gizmos.m_arrowIndices);
+
+	createPair("GizmosScale", ConstWeakArray<F32>(&g_gizmoScalePositions[0][0], sizeof(g_gizmoScalePositions) / sizeof(F32)),
+			   ConstWeakArray<U16>(&g_gizmoScaleIndices[0][0], sizeof(g_gizmoScaleIndices) / sizeof(U16)), m_gizmos.m_scalePositions,
+			   m_gizmos.m_scaleIndices);
+
+	createPair("GizmosRing", ConstWeakArray<F32>(&g_gizmoRingPositions[0][0], sizeof(g_gizmoRingPositions) / sizeof(F32)),
+			   ConstWeakArray<U16>(&g_gizmoRingIndices[0][0], sizeof(g_gizmoRingIndices) / sizeof(U16)), m_gizmos.m_ringPositions,
+			   m_gizmos.m_ringIndices);
+}
+
 void Dbg::drawNonRenderable(GpuSceneNonRenderableObjectType type, U32 objCount, const RenderingContext& ctx, const ImageResource& image,
 							CommandBuffer& cmdb)
 {
@@ -346,7 +563,14 @@ void Dbg::populateRenderGraphMain(RenderingContext& ctx)
 			}
 		}
 
+		if(m_gizmos.m_enabled)
+		{
+			cmdb.setDepthCompareOperation(CompareOperation::kAlways);
+			drawGizmos(m_gizmos.m_trf, ctx, cmdb);
+		}
+
 		// Restore state
+		cmdb.setBlendFactors(0, BlendFactor::kOne, BlendFactor::kZero);
 		cmdb.setDepthCompareOperation(CompareOperation::kLess);
 		cmdb.setDepthWrite(true);
 	});
@@ -541,4 +765,47 @@ void Dbg::populateRenderGraphObjectPicking(RenderingContext& ctx)
 	}
 }
 
+void Dbg::drawGizmos(const Mat3x4& worldTransform, const RenderingContext& ctx, CommandBuffer& cmdb) const
+{
+	auto draw = [&](Vec4 color, Euler rotation, Vec3 scale, Buffer& positionsBuff, Buffer& indexBuff) {
+		struct Consts
+		{
+			Mat4 m_mvp;
+			Vec4 m_color;
+		} consts;
+		consts.m_mvp = ctx.m_matrices.m_viewProjection * Mat4(worldTransform, Vec4(0.0f, 0.0f, 0.0f, 1.0f)) * Mat4(Vec3(0.0f), Mat3(rotation), scale);
+		consts.m_color = color;
+		cmdb.setFastConstants(&consts, sizeof(consts));
+
+		cmdb.setVertexAttribute(VertexAttributeSemantic::kPosition, 0, Format::kR32G32B32_Sfloat, 0);
+		cmdb.bindVertexBuffer(0, BufferView(&positionsBuff), sizeof(Vec3));
+
+		cmdb.bindIndexBuffer(BufferView(&indexBuff), IndexType::kU16);
+
+		cmdb.drawIndexed(PrimitiveTopology::kTriangles, U32(indexBuff.getSize() / sizeof(U16)));
+	};
+
+	ShaderProgramResourceVariantInitInfo variantInitInfo(m_dbgProg);
+	variantInitInfo.addMutation("OBJECT_TYPE", 0);
+	variantInitInfo.requestTechniqueAndTypes(ShaderTypeBit::kVertex | ShaderTypeBit::kPixel, "Gizmos");
+	const ShaderProgramResourceVariant* variant;
+	m_dbgProg->getOrCreateVariant(variantInitInfo, variant);
+	cmdb.bindShaderProgram(&variant->getProgram());
+
+	const F32 alpha = 1.0f;
+	draw(Vec4(1.0f, 0.0f, 0.0f, alpha), Euler(0.0f, kPi / 2.0f, 0.0f), Vec3(1.0f), *m_gizmos.m_arrowPositions, *m_gizmos.m_arrowIndices);
+	draw(Vec4(1.0f, 0.0f, 0.0f, alpha), Euler(0.0f, kPi / 2.0f, 0.0f), Vec3(0.95f, 0.95f, 0.6f), *m_gizmos.m_scalePositions,
+		 *m_gizmos.m_scaleIndices);
+	draw(Vec4(1.0f, 0.0f, 0.0f, alpha), Euler(0.0f, kPi / 2.0f, 0.0f), Vec3(0.4f), *m_gizmos.m_ringPositions, *m_gizmos.m_ringIndices);
+
+	draw(Vec4(0.0f, 1.0f, 0.0f, alpha), Euler(-kPi / 2.0f, 0.0f, 0.0f), Vec3(1.0f), *m_gizmos.m_arrowPositions, *m_gizmos.m_arrowIndices);
+	draw(Vec4(0.0f, 1.0f, 0.0f, alpha), Euler(-kPi / 2.0f, 0.0f, 0.0f), Vec3(0.95f, 0.95f, 0.6f), *m_gizmos.m_scalePositions,
+		 *m_gizmos.m_scaleIndices);
+	draw(Vec4(0.0f, 1.0f, 0.0f, alpha), Euler(-kPi / 2.0f, 0.0f, 0.0f), Vec3(0.4f), *m_gizmos.m_ringPositions, *m_gizmos.m_ringIndices);
+
+	draw(Vec4(0.0f, 0.0f, 1.0f, alpha), Euler(0.0f, 0.0f, 0.0f), Vec3(1.0f), *m_gizmos.m_arrowPositions, *m_gizmos.m_arrowIndices);
+	draw(Vec4(0.0f, 0.0f, 1.0f, alpha), Euler(0.0f, 0.0f, 0.0f), Vec3(0.95f, 0.95f, 0.6f), *m_gizmos.m_scalePositions, *m_gizmos.m_scaleIndices);
+	draw(Vec4(0.0f, 0.0f, 1.0f, alpha), Euler(0.0f, 0.0f, 0.0f), Vec3(0.4f), *m_gizmos.m_ringPositions, *m_gizmos.m_ringIndices);
+}
+
 } // end namespace anki

+ 24 - 0
AnKi/Renderer/Dbg.h

@@ -76,6 +76,12 @@ public:
 		return m_runCtx.m_objUuid;
 	}
 
+	void setGizmosTransform(const Transform& trf, Bool enableGizmos)
+	{
+		m_gizmos.m_trf = Mat3x4(trf.getOrigin().xyz(), trf.getRotation().getRotationPart());
+		m_gizmos.m_enabled = enableGizmos;
+	}
+
 private:
 	RenderTargetDesc m_rtDescr;
 	RenderTargetDesc m_objectPickingRtDescr;
@@ -94,6 +100,20 @@ private:
 
 	MultiframeReadbackToken m_readback;
 
+	class
+	{
+	public:
+		BufferPtr m_arrowPositions;
+		BufferPtr m_arrowIndices;
+		BufferPtr m_scalePositions;
+		BufferPtr m_scaleIndices;
+		BufferPtr m_ringPositions;
+		BufferPtr m_ringIndices;
+
+		Mat3x4 m_trf;
+		Bool m_enabled = false;
+	} m_gizmos;
+
 	DbgOption m_options = DbgOption::kDepthTest;
 
 	class
@@ -103,12 +123,16 @@ private:
 		U32 m_objUuid = 0;
 	} m_runCtx;
 
+	void initGizmos();
+
 	void populateRenderGraphMain(RenderingContext& ctx);
 
 	void populateRenderGraphObjectPicking(RenderingContext& ctx);
 
 	void drawNonRenderable(GpuSceneNonRenderableObjectType type, U32 objCount, const RenderingContext& ctx, const ImageResource& image,
 						   CommandBuffer& cmdb);
+
+	void drawGizmos(const Mat3x4& worldTransform, const RenderingContext& ctx, CommandBuffer& cmdb) const;
 };
 
 } // end namespace anki

+ 31 - 1
AnKi/Shaders/Dbg.ankiprog

@@ -18,6 +18,8 @@
 // Pick one UUID at mouse position
 #pragma anki technique RenderableUuidsPick comp mutators
 
+#pragma anki technique Gizmos vert pixel mutators
+
 #include <AnKi/Shaders/Common.hlsl>
 #include <AnKi/Shaders/Include/GpuVisibilityTypes.h>
 #include <AnKi/Shaders/Include/GpuSceneTypes.h>
@@ -281,6 +283,35 @@ Vec4 main(VertOut input) : SV_TARGET0
 #	endif // ANKI_PIXEL_SHADER
 #endif // ANKI_TECHNIQUE_Lines
 
+// ===========================================================================
+// Gizmos                                                                    =
+// ===========================================================================
+#if ANKI_TECHNIQUE_Gizmos
+
+struct Consts
+{
+	Mat4 m_mvp;
+	Vec4 m_color;
+};
+
+ANKI_FAST_CONSTANTS(Consts, g_consts)
+
+#	if ANKI_VERTEX_SHADER
+Vec4 main(Vec3 positions : POSITION) : SV_POSITION
+{
+	return mul(g_consts.m_mvp, Vec4(positions, 1.0));
+}
+#	endif
+
+#	if ANKI_PIXEL_SHADER
+Vec4 main() : SV_TARGET0
+{
+	return g_consts.m_color;
+}
+#	endif
+
+#endif
+
 // ===========================================================================
 // PrepareRenderableUuids                                                    =
 // ===========================================================================
@@ -412,5 +443,4 @@ ANKI_FAST_CONSTANTS(Consts, g_consts);
 	const U32 uuid = g_uuidsTex[g_consts.m_mousePos].x;
 	g_outUuid[0] = uuid;
 }
-
 #endif