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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user