Fixed capsule auxgeom draw for lights and other aux geom issues

Signed-off-by: antonmic <56370189+antonmic@users.noreply.github.com>
monroegm-disable-blank-issue-2
antonmic 4 years ago
parent b44ce82435
commit 8587c8e033

@ -155,8 +155,10 @@ namespace AZ
enum AuxGeomShapeType
{
ShapeType_Sphere,
ShapeType_Hemisphere,
ShapeType_Cone,
ShapeType_Cylinder,
ShapeType_CylinderNoEnds, // Cylinder without disks on either end
ShapeType_Disk,
ShapeType_Quad,

@ -314,15 +314,35 @@ namespace AZ
AddShape(style, shape);
}
void AuxGeomDrawQueue::DrawSphere(
const AZ::Vector3& center,
Matrix3x3 CreateMatrix3x3FromDirection(const AZ::Vector3& direction)
{
Vector3 unitDirection(direction.GetNormalized());
Vector3 unitOrthogonal(direction.GetOrthogonalVector().GetNormalized());
Vector3 unitCross(unitOrthogonal.Cross(unitDirection));
return Matrix3x3::CreateFromColumns(unitOrthogonal, unitDirection, unitCross);
}
void AuxGeomDrawQueue::DrawSphere(const AZ::Vector3& center, float radius, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex)
{
DrawSphereCommon(center, AZ::Vector3::CreateAxisY(), radius, color, style, depthTest, depthWrite, faceCull, viewProjOverrideIndex, false);
}
void AuxGeomDrawQueue::DrawHemisphere(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex)
{
DrawSphereCommon(center, direction, radius, color, style, depthTest, depthWrite, faceCull, viewProjOverrideIndex, true);
}
void AuxGeomDrawQueue::DrawSphereCommon(
const AZ::Vector3& center,
const AZ::Vector3& direction,
float radius,
const AZ::Color& color,
DrawStyle style,
DepthTest depthTest,
DepthWrite depthWrite,
FaceCullMode faceCull,
int32_t viewProjOverrideIndex)
int32_t viewProjOverrideIndex,
bool isHemisphere)
{
if (radius <= 0.0f)
{
@ -330,12 +350,12 @@ namespace AZ
}
ShapeBufferEntry shape;
shape.m_shapeType = ShapeType_Sphere;
shape.m_shapeType = isHemisphere ? ShapeType_Hemisphere : ShapeType_Sphere;
shape.m_depthRead = ConvertRPIDepthTestFlag(depthTest);
shape.m_depthWrite = ConvertRPIDepthWriteFlag(depthWrite);
shape.m_faceCullMode = ConvertRPIFaceCullFlag(faceCull);
shape.m_color = color;
shape.m_rotationMatrix = Matrix3x3::CreateIdentity();
shape.m_rotationMatrix = CreateMatrix3x3FromDirection(direction);
shape.m_position = center;
shape.m_scale = AZ::Vector3(radius, radius, radius);
shape.m_pointSize = m_pointSize;
@ -362,13 +382,9 @@ namespace AZ
shape.m_faceCullMode = ConvertRPIFaceCullFlag(faceCull);
shape.m_color = color;
Vector3 unitDirection(direction.GetNormalized());
Vector3 unitOrthogonal(direction.GetOrthogonalVector().GetNormalized());
Vector3 unitCross(unitOrthogonal.Cross(unitDirection));
// The disk mesh is created with the top of the disk pointing along the positive Y axis. This creates a
// rotation so that the top of the disk will point along the given direction vector.
shape.m_rotationMatrix = Matrix3x3::CreateFromColumns(unitOrthogonal, unitDirection, unitCross);
shape.m_rotationMatrix = CreateMatrix3x3FromDirection(direction);
shape.m_position = center;
shape.m_scale = AZ::Vector3(radius, 1.0f, radius);
shape.m_pointSize = m_pointSize;
@ -401,13 +417,7 @@ namespace AZ
shape.m_faceCullMode = ConvertRPIFaceCullFlag(faceCull);
shape.m_color = color;
Vector3 unitDirection(direction.GetNormalized());
Vector3 unitOrthogonal(direction.GetOrthogonalVector().GetNormalized());
Vector3 unitCross(unitOrthogonal.Cross(unitDirection));
// The cone mesh is created with the tip of the cone pointing along the positive Y axis. This creates a
// rotation so that the tip of the cone will point along the given direction vector.
shape.m_rotationMatrix = Matrix3x3::CreateFromColumns(unitOrthogonal, unitDirection, unitCross);
shape.m_rotationMatrix = CreateMatrix3x3FromDirection(direction);
shape.m_position = center;
shape.m_scale = AZ::Vector3(radius, height, radius);
shape.m_pointSize = m_pointSize;
@ -416,17 +426,30 @@ namespace AZ
AddShape(style, shape);
}
void AuxGeomDrawQueue::DrawCylinder(
const AZ::Vector3& center,
const AZ::Vector3& direction,
float radius,
float height,
const AZ::Color& color,
DrawStyle style,
DepthTest depthTest,
DepthWrite depthWrite,
FaceCullMode faceCull,
int32_t viewProjOverrideIndex)
void AuxGeomDrawQueue::DrawCylinder(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, float height, const AZ::Color& color,
DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex)
{
DrawCylinderCommon(center, direction, radius, height, color, style, depthTest, depthWrite, faceCull, viewProjOverrideIndex, true);
}
void AuxGeomDrawQueue::DrawCylinderNoEnds(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, float height, const AZ::Color& color,
DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex)
{
DrawCylinderCommon(center, direction, radius, height, color, style, depthTest, depthWrite, faceCull, viewProjOverrideIndex, false);
}
void AuxGeomDrawQueue::DrawCylinderCommon(
const AZ::Vector3& center,
const AZ::Vector3& direction,
float radius,
float height,
const AZ::Color& color,
DrawStyle style,
DepthTest depthTest,
DepthWrite depthWrite,
FaceCullMode faceCull,
int32_t viewProjOverrideIndex,
bool drawEnds)
{
if (radius <= 0.0f || height <= 0.0f)
{
@ -434,19 +457,15 @@ namespace AZ
}
ShapeBufferEntry shape;
shape.m_shapeType = ShapeType_Cylinder;
shape.m_depthRead = ConvertRPIDepthTestFlag(depthTest);
shape.m_shapeType = drawEnds ? ShapeType_Cylinder : ShapeType_CylinderNoEnds;
shape.m_depthRead = ConvertRPIDepthTestFlag(depthTest);
shape.m_depthWrite = ConvertRPIDepthWriteFlag(depthWrite);
shape.m_faceCullMode = ConvertRPIFaceCullFlag(faceCull);
shape.m_color = color;
Vector3 unitDirection(direction.GetNormalized());
Vector3 unitOrthogonal(direction.GetOrthogonalVector().GetNormalized());
Vector3 unitCross(unitOrthogonal.Cross(unitDirection));
// The cylinder mesh is created with the top end cap of the cylinder facing along the positive Y axis. This creates a
// rotation so that the top face of the cylinder will face along the given direction vector.
shape.m_rotationMatrix = Matrix3x3::CreateFromColumns(unitOrthogonal, unitDirection, unitCross);
shape.m_rotationMatrix = CreateMatrix3x3FromDirection(direction);
shape.m_position = center;
shape.m_scale = AZ::Vector3(radius, height, radius);
shape.m_pointSize = m_pointSize;

@ -60,9 +60,11 @@ namespace AZ
// Fixed shape draws
void DrawQuad(float width, float height, const AZ::Matrix3x4& transform, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
void DrawSphere(const AZ::Vector3& center, float radius, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
void DrawHemisphere(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
void DrawDisk(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
void DrawCone(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, float height, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
void DrawCylinder(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, float height, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
void DrawCylinderNoEnds(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, float height, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
void DrawAabb(const AZ::Aabb& aabb, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
void DrawAabb(const AZ::Aabb& aabb, const AZ::Matrix3x4& transform, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
void DrawObb(const AZ::Obb& obb, const AZ::Vector3& position, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
@ -73,6 +75,9 @@ namespace AZ
private: // functions
void DrawCylinderCommon(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, float height, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex, bool drawEnds);
void DrawSphereCommon(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex, bool isHemisphere);
//! Clear the current buffers
void ClearCurrentBufferData();

@ -10,6 +10,7 @@
#include "AuxGeomDrawProcessorShared.h"
#include <AzCore/Debug/EventTrace.h>
#include <AzCore/std/algorithm.h>
#include <AzCore/std/containers/array.h>
#include <Atom/RHI/Factory.h>
@ -69,11 +70,13 @@ namespace AZ
SetupInputStreamLayout(m_objectStreamLayout[DrawStyle_Solid], RHI::PrimitiveTopology::TriangleList, false);
SetupInputStreamLayout(m_objectStreamLayout[DrawStyle_Shaded], RHI::PrimitiveTopology::TriangleList, true);
CreateSphereBuffersAndViews();
CreateSphereBuffersAndViews(AuxGeomShapeType::ShapeType_Sphere);
CreateSphereBuffersAndViews(AuxGeomShapeType::ShapeType_Hemisphere);
CreateQuadBuffersAndViews();
CreateDiskBuffersAndViews();
CreateConeBuffersAndViews();
CreateCylinderBuffersAndViews();
CreateCylinderBuffersAndViews(AuxGeomShapeType::ShapeType_Cylinder);
CreateCylinderBuffersAndViews(AuxGeomShapeType::ShapeType_CylinderNoEnds);
CreateBoxBuffersAndViews();
// cache scene pointer for RHI::PipelineState creation.
@ -293,8 +296,11 @@ namespace AZ
}
}
bool FixedShapeProcessor::CreateSphereBuffersAndViews()
bool FixedShapeProcessor::CreateSphereBuffersAndViews(AuxGeomShapeType sphereShapeType)
{
AZ_Assert(sphereShapeType == ShapeType_Sphere || sphereShapeType == ShapeType_Hemisphere,
"Trying to create sphere buffers and views with a non-sphere shape type!");
const uint32_t numSphereLods = 5;
struct LodInfo
{
@ -311,13 +317,13 @@ namespace AZ
{ 9, 9, 0.0000f}
}};
auto& m_shape = m_shapes[ShapeType_Sphere];
auto& m_shape = m_shapes[sphereShapeType];
m_shape.m_numLods = numSphereLods;
for (uint32_t lodIndex = 0; lodIndex < numSphereLods; ++lodIndex)
{
MeshData meshData;
CreateSphereMeshData(meshData, lodInfo[lodIndex].numRings, lodInfo[lodIndex].numSections);
CreateSphereMeshData(meshData, lodInfo[lodIndex].numRings, lodInfo[lodIndex].numSections, sphereShapeType);
ObjectBuffers objectBuffers;
@ -334,12 +340,25 @@ namespace AZ
return true;
}
void FixedShapeProcessor::CreateSphereMeshData(MeshData& meshData, uint32_t numRings, uint32_t numSections)
void FixedShapeProcessor::CreateSphereMeshData(MeshData& meshData, uint32_t numRings, uint32_t numSections, AuxGeomShapeType sphereShapeType)
{
const float radius = 1.0f;
// calculate "inner" vertices
float sectionAngle(DegToRad(360.0f / static_cast<float>(numSections)));
float ringSlice(DegToRad(180.0f / static_cast<float>(numRings)));
uint32_t numberOfPoles = 2;
if (sphereShapeType == ShapeType_Hemisphere)
{
numberOfPoles = 1;
numRings = (numRings + 1) / 2;
ringSlice = DegToRad(90.0f / static_cast<float>(numRings));
}
// calc required number of vertices/indices/triangles to build a sphere for the given parameters
uint32_t numVertices = (numRings - 1) * numSections + 2;
uint32_t numVertices = (numRings - 1) * numSections + numberOfPoles;
// setup buffers
auto& positions = meshData.m_positions;
@ -354,30 +373,29 @@ namespace AZ
using NormalType = AuxGeomNormal;
// 1st pole vertex
positions.push_back(PosType(0.0f, 0.0f, radius));
normals.push_back(NormalType(0.0f, 0.0f, 1.0f));
positions.push_back(PosType(0.0f, radius, 0.0f));
normals.push_back(NormalType(0.0f, 1.0f, 0.0f));
// calculate "inner" vertices
float sectionAngle(DegToRad(360.0f / static_cast<float>(numSections)));
float ringSlice(DegToRad(180.0f / static_cast<float>(numRings)));
for (uint32_t ring = 1; ring < numRings; ++ring)
for (uint32_t ring = 1; ring < numRings - numberOfPoles + 2; ++ring)
{
float w(sinf(ring * ringSlice));
for (uint32_t section = 0; section < numSections; ++section)
{
float x = radius * cosf(section * sectionAngle) * w;
float y = radius * sinf(section * sectionAngle) * w;
float z = radius * cosf(ring * ringSlice);
float y = radius * cosf(ring * ringSlice);
float z = radius * sinf(section * sectionAngle) * w;
Vector3 radialVector(x, y, z);
positions.push_back(radialVector);
normals.push_back(radialVector.GetNormalized());
}
}
// 2nd vertex of pole (for end cap)
positions.push_back(PosType(0.0f, 0.0f, -radius));
normals.push_back(NormalType(0.0f, 0.0f, -1.0f));
if (sphereShapeType == ShapeType_Sphere)
{
// 2nd vertex of pole (for end cap)
positions.push_back(PosType(0.0f, -radius, 0.0f));
normals.push_back(NormalType(0.0f, -1.0f, 0.0f));
}
// point indices
{
@ -393,7 +411,8 @@ namespace AZ
// line indices
{
const uint32_t numEdges = (numRings - 2) * numSections * 2 + 2 * numSections * 2;
// NumEdges = NumRingEdges + NumSectionEdges = (numRings * numSections) + (numRings * numSections)
const uint32_t numEdges = numRings * numSections * 2;
const uint32_t numLineIndices = numEdges * 2;
// build "inner" faces
@ -401,10 +420,9 @@ namespace AZ
indices.clear();
indices.reserve(numLineIndices);
for (uint16_t ring = 0; ring < numRings - 2; ++ring)
for (uint16_t ring = 0; ring < numRings - numberOfPoles + 1; ++ring)
{
uint16_t firstVertOfThisRing = static_cast<uint16_t>(1 + ring * numSections);
uint16_t firstVertOfNextRing = static_cast<uint16_t>(1 + (ring + 1) * numSections);
for (uint16_t section = 0; section < numSections; ++section)
{
uint32_t nextSection = (section + 1) % numSections;
@ -414,32 +432,33 @@ namespace AZ
indices.push_back(static_cast<uint16_t>(firstVertOfThisRing + nextSection));
// line around section
indices.push_back(firstVertOfThisRing + section);
indices.push_back(firstVertOfNextRing + section);
int currentVertexIndex = firstVertOfThisRing + section;
// max 0 will implicitly handle the top pole
int previousVertexIndex = AZStd::max(currentVertexIndex - (int)numSections, 0);
indices.push_back(static_cast<uint16_t>(currentVertexIndex));
indices.push_back(static_cast<uint16_t>(previousVertexIndex));
}
}
// build faces for end caps (to connect "inner" vertices with poles)
uint16_t firstPoleVert = 0;
uint16_t firstVertOfFirstRing = static_cast<uint16_t>(1 + (0) * numSections);
for (uint16_t section = 0; section < numSections; ++section)
{
indices.push_back(firstPoleVert);
indices.push_back(firstVertOfFirstRing + section);
}
uint16_t lastPoleVert = static_cast<uint16_t>((numRings - 1) * numSections + 1);
uint16_t firstVertOfLastRing = static_cast<uint16_t>(1 + (numRings - 2) * numSections);
for (uint16_t section = 0; section < numSections; ++section)
if (sphereShapeType == ShapeType_Sphere)
{
indices.push_back(firstVertOfLastRing + section);
indices.push_back(lastPoleVert);
// build faces for bottom pole (to connect "inner" vertices with poles)
uint16_t lastPoleVert = static_cast<uint16_t>((numRings - 1) * numSections + 1);
uint16_t firstVertOfLastRing = static_cast<uint16_t>(1 + (numRings - 2) * numSections);
for (uint16_t section = 0; section < numSections; ++section)
{
indices.push_back(firstVertOfLastRing + section);
indices.push_back(lastPoleVert);
}
}
}
// triangle indices
{
const uint32_t numTriangles = (numRings - 2) * numSections * 2 + 2 * numSections;
// NumTriangles = NumTrianglesAtPoles + NumQuads * 2
// = (numSections * 2) + ((numRings - 2) * numSections * 2)
// = (numSections * 2) * (numRings - 2 + 1)
const uint32_t numTriangles = (numRings - 1) * numSections * 2;
const uint32_t numTriangleIndices = numTriangles * 3;
// build "inner" faces
@ -447,10 +466,10 @@ namespace AZ
indices.clear();
indices.reserve(numTriangleIndices);
for (uint32_t ring = 0; ring < numRings - 2; ++ring)
for (uint32_t ring = 0; ring < numRings - numberOfPoles; ++ring)
{
uint32_t firstVertOfThisRing = 1 + ring * numSections;
uint32_t firstVertOfNextRing = 1 + (ring + 1) * numSections;
uint32_t firstVertOfNextRing = firstVertOfThisRing + numSections;
for (uint32_t section = 0; section < numSections; ++section)
{
@ -476,14 +495,17 @@ namespace AZ
indices.push_back(static_cast<uint16_t>(firstPoleVert));
}
uint32_t lastPoleVert = (numRings - 1) * numSections + 1;
uint32_t firstVertOfLastRing = 1 + (numRings - 2) * numSections;
for (uint32_t section = 0; section < numSections; ++section)
if (sphereShapeType == ShapeType_Sphere)
{
uint32_t nextSection = (section + 1) % numSections;
indices.push_back(static_cast<uint16_t>(firstVertOfLastRing + nextSection));
indices.push_back(static_cast<uint16_t>(firstVertOfLastRing + section));
indices.push_back(static_cast<uint16_t>(lastPoleVert));
uint32_t lastPoleVert = (numRings - 1) * numSections + 1;
uint32_t firstVertOfLastRing = 1 + (numRings - 2) * numSections;
for (uint32_t section = 0; section < numSections; ++section)
{
uint32_t nextSection = (section + 1) % numSections;
indices.push_back(static_cast<uint16_t>(firstVertOfLastRing + nextSection));
indices.push_back(static_cast<uint16_t>(firstVertOfLastRing + section));
indices.push_back(static_cast<uint16_t>(lastPoleVert));
}
}
}
}
@ -827,8 +849,11 @@ namespace AZ
}
}
bool FixedShapeProcessor::CreateCylinderBuffersAndViews()
bool FixedShapeProcessor::CreateCylinderBuffersAndViews(AuxGeomShapeType cylinderShapeType)
{
AZ_Assert(cylinderShapeType == ShapeType_Cylinder || cylinderShapeType == ShapeType_CylinderNoEnds,
"Trying to create cylinder buffers and views with a non-cylinder shape type!");
const uint32_t numCylinderLods = 5;
struct LodInfo
{
@ -836,21 +861,21 @@ namespace AZ
float screenPercentage;
};
const AZStd::array<LodInfo, numCylinderLods> lodInfo =
{{
{ {
{ 38, 0.1000f},
{ 22, 0.0100f},
{ 14, 0.0010f},
{ 10, 0.0001f},
{ 8, 0.0000f}
}};
} };
auto& m_shape = m_shapes[ShapeType_Cylinder];
auto& m_shape = m_shapes[cylinderShapeType];
m_shape.m_numLods = numCylinderLods;
for (uint32_t lodIndex = 0; lodIndex < numCylinderLods; ++lodIndex)
{
MeshData meshData;
CreateCylinderMeshData(meshData, lodInfo[lodIndex].numSections);
CreateCylinderMeshData(meshData, lodInfo[lodIndex].numSections, cylinderShapeType);
ObjectBuffers objectBuffers;
@ -867,13 +892,25 @@ namespace AZ
return true;
}
void FixedShapeProcessor::CreateCylinderMeshData(MeshData& meshData, uint32_t numSections)
void FixedShapeProcessor::CreateCylinderMeshData(MeshData& meshData, uint32_t numSections, AuxGeomShapeType cylinderShapeType)
{
const float radius = 1.0f;
const float height = 1.0f;
//uint16_t indexOfBottomCenter = 0;
//uint16_t indexOfBottomStart = 1;
//uint16_t indexOfTopCenter = numSections + 1;
//uint16_t indexOfTopStart = numSections + 2;
uint16_t indexOfSidesStart = static_cast<uint16_t>(2 * numSections + 2);
if (cylinderShapeType == ShapeType_CylinderNoEnds)
{
// We won't draw disks at the ends of the cylinder, so no need to offset side indices
indexOfSidesStart = 0;
}
// calc required number of vertices to build a cylinder for the given parameters
uint32_t numVertices = 4 * numSections + 2;
uint32_t numVertices = indexOfSidesStart + 2 * numSections;
// setup buffers
auto& positions = meshData.m_positions;
@ -888,8 +925,11 @@ namespace AZ
float topHeight = height * 0.5f;
// Create caps
CreateDiskMeshData(meshData, numSections, Facing::Down, bottomHeight);
CreateDiskMeshData(meshData, numSections, Facing::Up, topHeight);
if (cylinderShapeType == ShapeType_Cylinder)
{
CreateDiskMeshData(meshData, numSections, Facing::Down, bottomHeight);
CreateDiskMeshData(meshData, numSections, Facing::Up, topHeight);
}
// create vertices for side (so normal points out correctly)
float sectionAngle(DegToRad(360.0f / (float)numSections));
@ -906,12 +946,6 @@ namespace AZ
normals.push_back(normal);
}
//uint16_t indexOfBottomCenter = 0;
//uint16_t indexOfBottomStart = 1;
//uint16_t indexOfTopCenter = numSections + 1;
//uint16_t indexOfTopStart = numSections + 2;
uint16_t indexOfSidesStart = static_cast<uint16_t>(2 * numSections + 2);
// build point indices
{
auto& indices = meshData.m_pointIndices;
@ -930,6 +964,24 @@ namespace AZ
indices.push_back(indexOfSidesStart + 2 * section);
indices.push_back(indexOfSidesStart + 2 * section + 1);
}
// If we're not drawing the disks at the ends of the cylinder, we still want to
// draw a ring around the end to join the tips of lines we created just above
if (cylinderShapeType == ShapeType_CylinderNoEnds)
{
for (uint16_t section = 0; section < numSections; ++section)
{
uint16_t nextSection = (section + 1) % numSections;
// line around the bottom cap
indices.push_back(section * 2);
indices.push_back(nextSection * 2);
// line around the top cap
indices.push_back(section * 2 + 1);
indices.push_back(nextSection * 2 + 1);
}
}
}
// indices for triangles

@ -138,8 +138,8 @@ namespace AZ
Both,
};
bool CreateSphereBuffersAndViews();
void CreateSphereMeshData(MeshData& meshData, uint32_t numRings, uint32_t numSections);
bool CreateSphereBuffersAndViews(AuxGeomShapeType sphereShapeType);
void CreateSphereMeshData(MeshData& meshData, uint32_t numRings, uint32_t numSections, AuxGeomShapeType sphereShapeType);
bool CreateQuadBuffersAndViews();
void CreateQuadMeshDataSide(MeshData& meshData, bool isUp, bool drawLines);
@ -152,8 +152,8 @@ namespace AZ
bool CreateConeBuffersAndViews();
void CreateConeMeshData(MeshData& meshData, uint32_t numRings, uint32_t numSections);
bool CreateCylinderBuffersAndViews();
void CreateCylinderMeshData(MeshData& meshData, uint32_t numSections);
bool CreateCylinderBuffersAndViews(AuxGeomShapeType cylinderShapeType);
void CreateCylinderMeshData(MeshData& meshData, uint32_t numSections, AuxGeomShapeType cylinderShapeType);
bool CreateBoxBuffersAndViews();
void CreateBoxMeshData(MeshData& meshData);

@ -147,6 +147,17 @@ namespace AZ
//! @param viewProjOverrideIndex Which view projection override entry to use, -1 if unused
virtual void DrawSphere( const AZ::Vector3& center, float radius, const AZ::Color& color, DrawStyle style = DrawStyle::Shaded, DepthTest depthTest = DepthTest::On, DepthWrite depthWrite = DepthWrite::On, FaceCullMode faceCull = FaceCullMode::Back, int32_t viewProjOverrideIndex = -1) = 0;
//! Draw a hemisphere.
//! @param center The center of the sphere.
//! @param radius The radius.
//! @param color The color to draw the sphere.
//! @param style The draw style (point, wireframe, solid, shaded etc).
//! @param depthTest If depth testing should be enabled
//! @param depthWrite If depth writing should be enabled
//! @param faceCull Which (if any) facing triangles should be culled
//! @param viewProjOverrideIndex Which view projection override entry to use, -1 if unused
virtual void DrawHemisphere( const AZ::Vector3& center, const AZ::Vector3& direction, float radius, const AZ::Color& color, DrawStyle style = DrawStyle::Shaded, DepthTest depthTest = DepthTest::On, DepthWrite depthWrite = DepthWrite::On, FaceCullMode faceCull = FaceCullMode::Back, int32_t viewProjOverrideIndex = -1) = 0;
//! Draw a disk.
//! @param center The center of the disk.
//! @param direction The direction vector. The disk will be orthogonal this vector.
@ -172,7 +183,7 @@ namespace AZ
//! @param viewProjOverrideIndex Which view projection override entry to use, -1 if unused
virtual void DrawCone(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, float height, const AZ::Color& color, DrawStyle style = DrawStyle::Shaded, DepthTest depthTest = DepthTest::On, DepthWrite depthWrite = DepthWrite::On, FaceCullMode faceCull = FaceCullMode::Back, int32_t viewProjOverrideIndex = -1) = 0;
//! Draw a cylinder.
//! Draw a cylinder (with flat disks on the end).
//! @param center The center of the base circle.
//! @param direction The direction vector. The top end cap of the cylinder will face along this vector.
//! @param radius The radius.
@ -185,6 +196,19 @@ namespace AZ
//! @param viewProjOverrideIndex Which view projection override entry to use, -1 if unused
virtual void DrawCylinder(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, float height, const AZ::Color& color, DrawStyle style = DrawStyle::Shaded, DepthTest depthTest = DepthTest::On, DepthWrite depthWrite = DepthWrite::On, FaceCullMode faceCull = FaceCullMode::Back, int32_t viewProjOverrideIndex = -1) = 0;
//! Draw a cylinder without flat disk on the end.
//! @param center The center of the base circle.
//! @param direction The direction vector. The top end cap of the cylinder will face along this vector.
//! @param radius The radius.
//! @param height The height of the cylinder.
//! @param color The color to draw the cylinder.
//! @param style The draw style (point, wireframe, solid, shaded etc).
//! @param depthTest If depth testing should be enabled
//! @param depthWrite If depth writing should be enabled
//! @param faceCull Which (if any) facing triangles should be culled
//! @param viewProjOverrideIndex Which view projection override entry to use, -1 if unused
virtual void DrawCylinderNoEnds(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, float height, const AZ::Color& color, DrawStyle style = DrawStyle::Shaded, DepthTest depthTest = DepthTest::On, DepthWrite depthWrite = DepthWrite::On, FaceCullMode faceCull = FaceCullMode::Back, int32_t viewProjOverrideIndex = -1) = 0;
//! Draw an axis-aligned bounding box with no transform.
//! @param aabb The AABB (typically the bounding box of a set of world space points).
//! @param color The color to draw the box.

@ -1025,83 +1025,57 @@ namespace AZ::AtomBridge
if (m_auxGeomPtr && radius > FLT_EPSILON && axis.GetLengthSq() > FLT_EPSILON)
{
AZ::Vector3 axisNormalized = axis.GetNormalizedEstimate();
SingleColorStaticSizeLineHelper<(16+1) * 5> lines; // 360/22.5 = 16, 5 possible calls to CreateArbitraryAxisArc
AZ::Vector3 radiusV3 = AZ::Vector3(radius);
float stepAngle = DegToRad(22.5f);
float Deg0 = DegToRad(0.0f);
const float scale = GetCurrentTransform().RetrieveScale().GetMaxElement();
const AZ::Vector3 worldCenter = ToWorldSpacePosition(center);
const AZ::Vector3 worldAxis = ToWorldSpaceVector(axis);
// Draw cylinder part (or just a circle around the middle)
if (heightStraightSection > FLT_EPSILON)
{
DrawWireCylinder(center, axis, radius, heightStraightSection);
}
else
{
float Deg360 = DegToRad(360.0f);
CreateArbitraryAxisArc(
lines,
stepAngle,
Deg0,
Deg360,
center,
radiusV3,
axisNormalized
);
m_auxGeomPtr->DrawCylinderNoEnds(
worldCenter,
worldAxis,
scale * radius,
scale * heightStraightSection,
m_rendState.m_color,
AZ::RPI::AuxGeomDraw::DrawStyle::Line,
m_rendState.m_depthTest,
m_rendState.m_depthWrite,
m_rendState.m_faceCullMode,
m_rendState.m_viewProjOverrideIndex
);
}
float Deg90 = DegToRad(90.0f);
float Deg180 = DegToRad(180.0f);
AZ::Vector3 ortho1Normalized, ortho2Normalized;
CalcBasisVectors(axisNormalized, ortho1Normalized, ortho2Normalized);
AZ::Vector3 centerToTopCircleCenter = axisNormalized * heightStraightSection * 0.5f;
AZ::Vector3 topCenter = center + centerToTopCircleCenter;
AZ::Vector3 bottomCenter = center - centerToTopCircleCenter;
// Draw top cap as two criss-crossing 180deg arcs
CreateArbitraryAxisArc(
lines,
stepAngle,
Deg90,
Deg90 + Deg180,
topCenter,
radiusV3,
ortho1Normalized
);
CreateArbitraryAxisArc(
lines,
stepAngle,
Deg180,
Deg180 + Deg180,
topCenter,
radiusV3,
ortho2Normalized
);
// Draw bottom cap
CreateArbitraryAxisArc(
lines,
stepAngle,
-Deg90,
-Deg90 + Deg180,
bottomCenter,
radiusV3,
ortho1Normalized
);
CreateArbitraryAxisArc(
lines,
stepAngle,
Deg0,
Deg0 + Deg180,
bottomCenter,
radiusV3,
ortho2Normalized
);
m_auxGeomPtr->DrawHemisphere(
topCenter,
worldAxis,
scale * radius,
m_rendState.m_color,
AZ::RPI::AuxGeomDraw::DrawStyle::Line,
m_rendState.m_depthTest,
m_rendState.m_depthWrite,
m_rendState.m_faceCullMode,
m_rendState.m_viewProjOverrideIndex
);
lines.Draw(m_auxGeomPtr, m_rendState);
m_auxGeomPtr->DrawHemisphere(
bottomCenter,
-worldAxis,
scale * radius,
m_rendState.m_color,
AZ::RPI::AuxGeomDraw::DrawStyle::Line,
m_rendState.m_depthTest,
m_rendState.m_depthWrite,
m_rendState.m_faceCullMode,
m_rendState.m_viewProjOverrideIndex
);
}
}

Loading…
Cancel
Save