Fixed capsule auxgeom draw for lights and other aux geom issues
Signed-off-by: antonmic <56370189+antonmic@users.noreply.github.com>
This commit is contained in:
@@ -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)
|
||||
if (sphereShapeType == ShapeType_Sphere)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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.
|
||||
|
||||
+37
-63
@@ -1025,33 +1025,27 @@ 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);
|
||||
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
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
float Deg360 = DegToRad(360.0f);
|
||||
CreateArbitraryAxisArc(
|
||||
lines,
|
||||
stepAngle,
|
||||
Deg0,
|
||||
Deg360,
|
||||
center,
|
||||
radiusV3,
|
||||
axisNormalized
|
||||
);
|
||||
}
|
||||
|
||||
float Deg90 = DegToRad(90.0f);
|
||||
float Deg180 = DegToRad(180.0f);
|
||||
|
||||
AZ::Vector3 ortho1Normalized, ortho2Normalized;
|
||||
CalcBasisVectors(axisNormalized, ortho1Normalized, ortho2Normalized);
|
||||
@@ -1059,49 +1053,29 @@ namespace AZ::AtomBridge
|
||||
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
|
||||
);
|
||||
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
|
||||
);
|
||||
|
||||
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
|
||||
);
|
||||
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user