mirror of
https://github.com/overte-org/overte.git
synced 2025-04-08 20:13:35 +02:00
[WL21389] WL21389 PR2: Representation of collision shapes need updating (details below).
This commit adds support for the polyhedrons and polygons sans Torus and Quad which aren't currently supported within GeometryCache. * Moves GeometryCache::_shapes from public to private scope * Nothing aside from the class should be directly altering this, only querying * Updated instances of direct referencing which looks to have been limited to prior testing of instancing and shapes. * Adds an accessor function for ShapeData to GeometryCache * Consolidates point list generation to helper function * GeometryCache::computeSimpleHullPointListForShape * Moves GeometryCache::Shape to entity::Shape mapping to GeometryCache from RenderableShapeEntityItem * Adds conversion accessor to GeometryCache, GeometryCache::Shape getShapeForEntityShape * Sets ShapeEntityItem::ShapeInfoCalculator callback committed earlier. * This helps circumvent the issue with library inclusion. entity-render knows about entity; however, entity doesn't know about entity-renderer; however, GeometryCache data is needed within entity::ShapeEntityItem to compose the ShapeInfo point list data. * This callback is set up within Application::init of the Interface as it knows about both halves of the equation, and the callback needs to be setup prior to any entities collision data getting generated. * Removes _type reset within ShapeInfo::setPointCollection * This should avoid any issues due to subversively setting the type or incorrectly setting the type as a tangential operation. * Audited instances of ShapeInfo::setPointCollection and all seemed to be calling the function immediately after having set the type via ShapeInfo::setParams * Adds new ShapeType: SHAPE_TYPE_CIRCLE * This type is reserved for the circle which is now treated as a special type of Cylinder_Y with regard to collision as opposed to a simple hull. * Fixes the issue where jumping on a circle, at times, would result in the avatar sliding off towards an edge as if atop a squished cone. * Also updates ShapeInfo::getType() to return ShapeType as opposed to int * Auditing calls showed that majority of places were comparing against ShapeType * ShapeType::_type is a ShapeType so returning the type explicitly is more consistent. * ShapeInfo file houses ShapeType enum so any file aware of ShapeInfo is aware of ShapeType enumeration. * entity::Quad defaults to SHAPE_TYPE_ELLIPSOID * Like entity::Shape::Torus, entity::Shape::Quad is currently unsupported within GeometryCache::buildShapes. * Also it appears that a Quad shape can't be created within world via the creation menu. * There's no explicit option at present to create one. * Trying subvert the Cube/Box creation option to generate one results in an enforced stubby box as opposed to a quad. * Given the aforementioned points, entity::Shape::Quad will default to SHAPE_TYPE_ELLIPSOID as opposed to SHAPE_TYPE_BOX. * Added Todo regarding the shape being unsupported along with a notation to create a special ShapeType, SHAPE_TYPE_QUAD, for it should it be added in the future. * Adds some comments and has some minor clean up. Reviewed-by: Leander Hasty <leander@1stplayable.com> Changes Committed: modified: interface/src/Application.cpp modified: interface/src/Util.cpp modified: interface/src/Util.h modified: libraries/entities-renderer/src/RenderableShapeEntityItem.cpp modified: libraries/entities/src/ShapeEntityItem.cpp modified: libraries/entities/src/ShapeEntityItem.h modified: libraries/physics/src/ShapeFactory.cpp modified: libraries/render-utils/src/GeometryCache.cpp modified: libraries/render-utils/src/GeometryCache.h modified: libraries/shared/src/ShapeInfo.cpp modified: libraries/shared/src/ShapeInfo.h modified: tests/gpu-test/src/TestInstancedShapes.cpp
This commit is contained in:
parent
9981a44b71
commit
5b50b362f1
12 changed files with 221 additions and 97 deletions
|
@ -120,6 +120,7 @@
|
|||
#include <SceneScriptingInterface.h>
|
||||
#include <ScriptEngines.h>
|
||||
#include <ScriptCache.h>
|
||||
#include <ShapeEntityItem.h>
|
||||
#include <SoundCache.h>
|
||||
#include <ui/TabletScriptingInterface.h>
|
||||
#include <ui/ToolbarScriptingInterface.h>
|
||||
|
@ -4228,6 +4229,10 @@ void Application::init() {
|
|||
// fire off an immediate domain-server check in now that settings are loaded
|
||||
DependencyManager::get<NodeList>()->sendDomainServerCheckIn();
|
||||
|
||||
// This allows collision to be set up properly for shape entities supported by GeometryCache.
|
||||
// This is before entity setup to ensure that it's ready for whenever instance collision is initialized.
|
||||
ShapeEntityItem::setShapeInfoCalulator(ShapeEntityItem::ShapeInfoCalculator(&shapeInfoCalculator));
|
||||
|
||||
getEntities()->init();
|
||||
getEntities()->setEntityLoadingPriorityFunction([this](const EntityItem& item) {
|
||||
auto dims = item.getDimensions();
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#include <GeometryCache.h>
|
||||
#include <OctreeConstants.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <ShapeEntityItem.h>
|
||||
#include <ShapeInfo.h>
|
||||
|
||||
#include "InterfaceLogging.h"
|
||||
#include "world.h"
|
||||
|
@ -393,4 +395,13 @@ void runUnitTests() {
|
|||
}
|
||||
}
|
||||
|
||||
void shapeInfoCalculator(const ShapeEntityItem * const shapeEntity, ShapeInfo &shapeInfo) {
|
||||
ShapeInfo::PointCollection pointCollection;
|
||||
ShapeInfo::PointList points;
|
||||
|
||||
GeometryCache::computeSimpleHullPointListForShape(shapeEntity, points);
|
||||
pointCollection.push_back(points);
|
||||
shapeInfo.setPointCollection(pointCollection);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
#include <gpu/Batch.h>
|
||||
#include <render/Forward.h>
|
||||
|
||||
class ShapeEntityItem;
|
||||
class ShapeInfo;
|
||||
|
||||
void renderWorldBox(RenderArgs* args, gpu::Batch& batch);
|
||||
|
||||
void runTimingTests();
|
||||
|
@ -28,4 +31,6 @@ bool rayIntersectsSphere(const glm::vec3& rayStarting, const glm::vec3& rayNorma
|
|||
|
||||
bool pointInSphere(glm::vec3& point, glm::vec3& sphereCenter, double sphereRadius);
|
||||
|
||||
void shapeInfoCalculator(const ShapeEntityItem * const shapeEntity, ShapeInfo &shapeInfo);
|
||||
|
||||
#endif // hifi_Util_h
|
||||
|
|
|
@ -30,23 +30,6 @@ using namespace render::entities;
|
|||
// is a half unit sphere. However, the geometry cache renders a UNIT sphere, so we need to scale down.
|
||||
static const float SPHERE_ENTITY_SCALE = 0.5f;
|
||||
|
||||
static std::array<GeometryCache::Shape, entity::NUM_SHAPES> MAPPING { {
|
||||
GeometryCache::Triangle,
|
||||
GeometryCache::Quad,
|
||||
GeometryCache::Hexagon,
|
||||
GeometryCache::Octagon,
|
||||
GeometryCache::Circle,
|
||||
GeometryCache::Cube,
|
||||
GeometryCache::Sphere,
|
||||
GeometryCache::Tetrahedron,
|
||||
GeometryCache::Octahedron,
|
||||
GeometryCache::Dodecahedron,
|
||||
GeometryCache::Icosahedron,
|
||||
GeometryCache::Torus,
|
||||
GeometryCache::Cone,
|
||||
GeometryCache::Cylinder,
|
||||
} };
|
||||
|
||||
|
||||
ShapeEntityRenderer::ShapeEntityRenderer(const EntityItemPointer& entity) : Parent(entity) {
|
||||
_procedural._vertexSource = simple_vert;
|
||||
|
@ -137,11 +120,12 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) {
|
|||
|
||||
gpu::Batch& batch = *args->_batch;
|
||||
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
GeometryCache::Shape geometryShape;
|
||||
bool proceduralRender = false;
|
||||
glm::vec4 outColor;
|
||||
withReadLock([&] {
|
||||
geometryShape = MAPPING[_shape];
|
||||
geometryShape = geometryCache->getShapeForEntityShape(_shape);
|
||||
batch.setModelTransform(_renderTransform); // use a transform with scale, rotation, registration point and translation
|
||||
outColor = _color;
|
||||
if (_procedural.isReady()) {
|
||||
|
@ -155,14 +139,13 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) {
|
|||
if (proceduralRender) {
|
||||
batch._glColor4f(outColor.r, outColor.g, outColor.b, outColor.a);
|
||||
if (render::ShapeKey(args->_globalShapeKey).isWireframe()) {
|
||||
DependencyManager::get<GeometryCache>()->renderWireShape(batch, geometryShape);
|
||||
geometryCache->renderWireShape(batch, geometryShape);
|
||||
} else {
|
||||
DependencyManager::get<GeometryCache>()->renderShape(batch, geometryShape);
|
||||
geometryCache->renderShape(batch, geometryShape);
|
||||
}
|
||||
} else {
|
||||
// FIXME, support instanced multi-shape rendering using multidraw indirect
|
||||
outColor.a *= _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f;
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
auto pipeline = outColor.a < 1.0f ? geometryCache->getTransparentShapePipeline() : geometryCache->getOpaqueShapePipeline();
|
||||
if (render::ShapeKey(args->_globalShapeKey).isWireframe()) {
|
||||
geometryCache->renderWireShapeInstance(args, batch, geometryShape, outColor, pipeline);
|
||||
|
@ -171,6 +154,6 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) {
|
|||
}
|
||||
}
|
||||
|
||||
static const auto triCount = DependencyManager::get<GeometryCache>()->getShapeTriangleCount(geometryShape);
|
||||
static const auto triCount = geometryCache->getShapeTriangleCount(geometryShape);
|
||||
args->_details._trianglesRendered += (int)triCount;
|
||||
}
|
||||
|
|
|
@ -241,79 +241,95 @@ void ShapeEntityItem::computeShapeInfo(ShapeInfo& info) {
|
|||
|
||||
const glm::vec3 entityDimensions = getDimensions();
|
||||
|
||||
switch (_shape) {
|
||||
case entity::Shape::Quad:
|
||||
case entity::Shape::Cube:
|
||||
{
|
||||
_collisionShapeType = SHAPE_TYPE_BOX;
|
||||
switch (_shape){
|
||||
case entity::Shape::Quad: {
|
||||
// Not in GeometryCache::buildShapes, unsupported.
|
||||
_collisionShapeType = SHAPE_TYPE_ELLIPSOID;
|
||||
//TODO WL21389: Add a SHAPE_TYPE_QUAD ShapeType and treat
|
||||
// as a special box (later if desired support)
|
||||
}
|
||||
break;
|
||||
case entity::Shape::Cube: {
|
||||
_collisionShapeType = SHAPE_TYPE_BOX;
|
||||
}
|
||||
break;
|
||||
case entity::Shape::Sphere: {
|
||||
|
||||
float diameter = entityDimensions.x;
|
||||
const float MIN_DIAMETER = 0.001f;
|
||||
const float MIN_RELATIVE_SPHERICAL_ERROR = 0.001f;
|
||||
if (diameter > MIN_DIAMETER
|
||||
&& fabsf(diameter - entityDimensions.y) / diameter < MIN_RELATIVE_SPHERICAL_ERROR
|
||||
&& fabsf(diameter - entityDimensions.z) / diameter < MIN_RELATIVE_SPHERICAL_ERROR) {
|
||||
|
||||
_collisionShapeType = SHAPE_TYPE_SPHERE;
|
||||
} else {
|
||||
_collisionShapeType = SHAPE_TYPE_ELLIPSOID;
|
||||
}
|
||||
break;
|
||||
case entity::Shape::Sphere:
|
||||
{
|
||||
}
|
||||
break;
|
||||
case entity::Shape::Circle: {
|
||||
_collisionShapeType = SHAPE_TYPE_CIRCLE;
|
||||
}
|
||||
break;
|
||||
case entity::Shape::Cylinder: {
|
||||
_collisionShapeType = SHAPE_TYPE_CYLINDER_Y;
|
||||
// TODO WL21389: determine if rotation is axis-aligned
|
||||
//const Transform::Quat & rot = _transform.getRotation();
|
||||
|
||||
float diameter = entityDimensions.x;
|
||||
const float MIN_DIAMETER = 0.001f;
|
||||
const float MIN_RELATIVE_SPHERICAL_ERROR = 0.001f;
|
||||
if (diameter > MIN_DIAMETER
|
||||
&& fabsf(diameter - entityDimensions.y) / diameter < MIN_RELATIVE_SPHERICAL_ERROR
|
||||
&& fabsf(diameter - entityDimensions.z) / diameter < MIN_RELATIVE_SPHERICAL_ERROR) {
|
||||
// TODO WL21389: some way to tell apart SHAPE_TYPE_CYLINDER_Y, _X, _Z based on rotation and
|
||||
// hull ( or dimensions, need circular cross section)
|
||||
// Should allow for minor variance along axes?
|
||||
|
||||
_collisionShapeType = SHAPE_TYPE_SPHERE;
|
||||
} else {
|
||||
_collisionShapeType = SHAPE_TYPE_ELLIPSOID;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case entity::Shape::Cylinder:
|
||||
{
|
||||
_collisionShapeType = SHAPE_TYPE_CYLINDER_Y;
|
||||
// TODO WL21389: determine if rotation is axis-aligned
|
||||
//const Transform::Quat & rot = _transform.getRotation();
|
||||
|
||||
// TODO WL21389: some way to tell apart SHAPE_TYPE_CYLINDER_Y, _X, _Z based on rotation and
|
||||
// hull ( or dimensions, need circular cross section)
|
||||
// Should allow for minor variance along axes?
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
// gons, ones, & angles built via GeometryCache::extrudePolygon
|
||||
case entity::Shape::Triangle:
|
||||
case entity::Shape::Hexagon:
|
||||
case entity::Shape::Octagon:
|
||||
case entity::Shape::Circle:
|
||||
case entity::Shape::Cone: {
|
||||
if (shapeCalculator) {
|
||||
shapeCalculator(this, info);
|
||||
// shapeCalculator only supports convex shapes (e.g. SHAPE_TYPE_HULL)
|
||||
// TODO: figure out how to support concave shapes
|
||||
_collisionShapeType = SHAPE_TYPE_SIMPLE_HULL;
|
||||
} else {
|
||||
_collisionShapeType = SHAPE_TYPE_ELLIPSOID;
|
||||
}
|
||||
}
|
||||
break;
|
||||
// hedrons built via GeometryCache::setUpFlatShapes
|
||||
case entity::Shape::Tetrahedron:
|
||||
case entity::Shape::Octahedron:
|
||||
case entity::Shape::Dodecahedron:
|
||||
case entity::Shape::Icosahedron:
|
||||
case entity::Shape::Cone:
|
||||
{
|
||||
if (shapeCalculator) {
|
||||
shapeCalculator(info, _shape, getDimensions());
|
||||
// shapeCalculator only supports convex shapes (e.g. SHAPE_TYPE_HULL)
|
||||
// TODO: figure out how to support concave shapes
|
||||
_collisionShapeType = SHAPE_TYPE_HULL;
|
||||
} else {
|
||||
_collisionShapeType = SHAPE_TYPE_ELLIPSOID;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case entity::Shape::Torus:
|
||||
{
|
||||
// Not in GeometryCache::buildShapes, unsupported.
|
||||
_collisionShapeType = SHAPE_TYPE_ELLIPSOID;
|
||||
//TODO WL21389: SHAPE_TYPE_SIMPLE_HULL and pointCollection (later if desired support)
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
case entity::Shape::Icosahedron: {
|
||||
if ( shapeCalculator ) {
|
||||
shapeCalculator(this, info);
|
||||
// shapeCalculator only supports convex shapes (e.g. SHAPE_TYPE_HULL)
|
||||
// TODO: figure out how to support concave shapes
|
||||
_collisionShapeType = SHAPE_TYPE_SIMPLE_HULL;
|
||||
} else {
|
||||
_collisionShapeType = SHAPE_TYPE_ELLIPSOID;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
case entity::Shape::Torus: {
|
||||
// Not in GeometryCache::buildShapes, unsupported.
|
||||
_collisionShapeType = SHAPE_TYPE_ELLIPSOID;
|
||||
//TODO WL21389: SHAPE_TYPE_SIMPLE_HULL and pointCollection (later if desired support)
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
_collisionShapeType = SHAPE_TYPE_ELLIPSOID;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
EntityItem::computeShapeInfo(info);
|
||||
}
|
||||
|
||||
// This value specifes how the shape should be treated by physics calculations.
|
||||
// This value specifies how the shape should be treated by physics calculations.
|
||||
ShapeType ShapeEntityItem::getShapeType() const {
|
||||
return _collisionShapeType;
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
static EntityItemPointer sphereFactory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
static EntityItemPointer boxFactory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
|
||||
using ShapeInfoCalculator = std::function<void(ShapeInfo& info, entity::Shape shape, glm::vec3 dimensions)>;
|
||||
using ShapeInfoCalculator = std::function<void( const ShapeEntityItem * const shapeEntity, ShapeInfo& info)>;
|
||||
static void setShapeInfoCalulator(ShapeInfoCalculator callback);
|
||||
|
||||
ShapeEntityItem(const EntityItemID& entityItemID);
|
||||
|
|
|
@ -314,6 +314,7 @@ const btCollisionShape* ShapeFactory::createShapeFromInfo(const ShapeInfo& info)
|
|||
shape = new btCylinderShapeZ(btHalfExtents);
|
||||
}
|
||||
break;
|
||||
case SHAPE_TYPE_CIRCLE:
|
||||
case SHAPE_TYPE_CYLINDER_Y: {
|
||||
const glm::vec3 halfExtents = info.getHalfExtents();
|
||||
const btVector3 btHalfExtents(halfExtents.x, halfExtents.y, halfExtents.z);
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include <FSTReader.h>
|
||||
#include <NumericalConstants.h>
|
||||
#include <ShapeEntityItem.h>
|
||||
|
||||
#include "TextureCache.h"
|
||||
#include "RenderUtilsLogging.h"
|
||||
|
@ -52,6 +53,24 @@
|
|||
|
||||
//#define WANT_DEBUG
|
||||
|
||||
static std::array<GeometryCache::Shape, entity::NUM_SHAPES> MAPPING{ {
|
||||
GeometryCache::Triangle,
|
||||
GeometryCache::Quad,
|
||||
GeometryCache::Hexagon,
|
||||
GeometryCache::Octagon,
|
||||
GeometryCache::Circle,
|
||||
GeometryCache::Cube,
|
||||
GeometryCache::Sphere,
|
||||
GeometryCache::Tetrahedron,
|
||||
GeometryCache::Octahedron,
|
||||
GeometryCache::Dodecahedron,
|
||||
GeometryCache::Icosahedron,
|
||||
GeometryCache::Torus,
|
||||
GeometryCache::Cone,
|
||||
GeometryCache::Cylinder,
|
||||
} };
|
||||
|
||||
|
||||
const int GeometryCache::UNKNOWN_ID = -1;
|
||||
|
||||
|
||||
|
@ -69,6 +88,52 @@ static gpu::Stream::FormatPointer INSTANCED_SOLID_FADE_STREAM_FORMAT;
|
|||
static const uint SHAPE_VERTEX_STRIDE = sizeof(glm::vec3) * 2; // vertices and normals
|
||||
static const uint SHAPE_NORMALS_OFFSET = sizeof(glm::vec3);
|
||||
|
||||
void GeometryCache::computeSimpleHullPointListForShape(const ShapeEntityItem * const shapePtr, QVector<glm::vec3> &outPointList){
|
||||
|
||||
if (shapePtr == nullptr){
|
||||
//--EARLY EXIT--
|
||||
return;
|
||||
}
|
||||
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
const GeometryCache::ShapeData * shapeData = geometryCache->getShapeData(MAPPING[shapePtr->getShape()]);
|
||||
if (!shapeData){
|
||||
//--EARLY EXIT--( data isn't ready for some reason... )
|
||||
return;
|
||||
}
|
||||
const gpu::BufferView & shapeVerts = shapeData->_positionView;
|
||||
const gpu::BufferView & shapeNorms = shapeData->_normalView;
|
||||
assert(shapeVerts._size == shapeNorms._size);
|
||||
|
||||
const gpu::BufferView::Size numItems = shapeVerts.getNumElements();
|
||||
const glm::vec3 halfExtents = shapePtr->getDimensions() * 0.5f;
|
||||
#if DEBUG_SIMPLE_HULL_POINT_GENERATION
|
||||
shapePtr->debugDump();
|
||||
qCDebug(entities) << "------------------ Begin Vert Info( ComputeShapeInfo )[FlatShapes] -----------------------------";
|
||||
qCDebug(entities) << " name:" << shapePtr->getName() << ": has " << numItems << " vert info pairs.";
|
||||
#endif
|
||||
outPointList.reserve(numItems);
|
||||
for (gpu::BufferView::Index i = 0; i < (gpu::BufferView::Index)numItems; ++i) {
|
||||
const geometry::Vec &curNorm = shapeNorms.get<geometry::Vec>(i);
|
||||
#if DEBUG_SIMPLE_HULL_POINT_GENERATION
|
||||
const geometry::Vec &curVert = shapeVerts.get<geometry::Vec>(i);
|
||||
qCDebug(entities) << " --------------------";
|
||||
qCDebug(entities) << " Vert( " << i << " ): " << debugTreeVector(curVert);
|
||||
qCDebug(entities) << " Norm( " << i << " ): " << debugTreeVector(curNorm);
|
||||
#endif
|
||||
outPointList.push_back(curNorm * halfExtents);
|
||||
|
||||
#if DEBUG_SIMPLE_HULL_POINT_GENERATION
|
||||
qCDebug(entities) << " Point( " << i << " ): " << debugTreeVector((curNorm * halfExtents));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if DEBUG_SIMPLE_HULL_POINT_GENERATION
|
||||
qCDebug(entities) << "-------------------- End Vert Info( ComputeShapeInfo ) -----------------------------";
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
template <size_t SIDES>
|
||||
std::vector<vec3> polygon() {
|
||||
std::vector<vec3> result;
|
||||
|
@ -447,6 +512,22 @@ void GeometryCache::buildShapes() {
|
|||
|
||||
}
|
||||
|
||||
const GeometryCache::ShapeData * GeometryCache::getShapeData(const Shape shape) const {
|
||||
if (((int)shape < 0) || ((int)shape >= _shapes.size())){
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &_shapes[shape];
|
||||
}
|
||||
|
||||
GeometryCache::Shape GeometryCache::getShapeForEntityShape(int entityShape) {
|
||||
if ((entityShape < 0) || (entityShape >= MAPPING.size())){
|
||||
return NUM_SHAPES;
|
||||
}
|
||||
|
||||
return MAPPING[entityShape];
|
||||
}
|
||||
|
||||
gpu::Stream::FormatPointer& getSolidStreamFormat() {
|
||||
if (!SOLID_STREAM_FORMAT) {
|
||||
SOLID_STREAM_FORMAT = std::make_shared<gpu::Stream::Format>(); // 1 for everyone
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <model/Asset.h>
|
||||
|
||||
class SimpleProgramKey;
|
||||
class ShapeEntityItem;
|
||||
|
||||
typedef QPair<glm::vec2, float> Vec2FloatPair;
|
||||
typedef QPair<Vec2FloatPair, Vec2FloatPair> Vec2FloatPairPair;
|
||||
|
@ -147,6 +148,15 @@ public:
|
|||
NUM_SHAPES,
|
||||
};
|
||||
|
||||
/// @param entityShapeEnum: The entity::Shape enumeration for the shape
|
||||
/// whose GeometryCache::Shape is desired.
|
||||
/// @return GeometryCache::NUM_SHAPES in the event of an error; otherwise,
|
||||
/// the GeometryCache::Shape enum which aligns with the
|
||||
/// specified entityShapeEnum
|
||||
static GeometryCache::Shape getShapeForEntityShape(int entityShapeEnum);
|
||||
|
||||
static void computeSimpleHullPointListForShape(const ShapeEntityItem * const shapePtr, QVector<glm::vec3> &outPointList);
|
||||
|
||||
static uint8_t CUSTOM_PIPELINE_NUMBER;
|
||||
static render::ShapePipelinePointer shapePipelineFactory(const render::ShapePlumber& plumber, const render::ShapeKey& key);
|
||||
static void registerShapePipeline() {
|
||||
|
@ -355,15 +365,21 @@ public:
|
|||
|
||||
using VShape = std::array<ShapeData, NUM_SHAPES>;
|
||||
|
||||
VShape _shapes;
|
||||
/// returns ShapeData associated with the specified shape,
|
||||
/// otherwise nullptr in the event of an error.
|
||||
const ShapeData * getShapeData(Shape shape) const;
|
||||
|
||||
private:
|
||||
|
||||
GeometryCache();
|
||||
virtual ~GeometryCache();
|
||||
void buildShapes();
|
||||
|
||||
typedef QPair<int, int> IntPair;
|
||||
typedef QPair<unsigned int, unsigned int> VerticesIndices;
|
||||
|
||||
|
||||
VShape _shapes;
|
||||
|
||||
gpu::PipelinePointer _standardDrawPipeline;
|
||||
gpu::PipelinePointer _standardDrawPipelineNoBlend;
|
||||
|
|
|
@ -45,6 +45,10 @@ void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QString
|
|||
_halfExtents = glm::vec3(radius);
|
||||
}
|
||||
break;
|
||||
case SHAPE_TYPE_CIRCLE: {
|
||||
_halfExtents = glm::vec3(_halfExtents.x, MIN_HALF_EXTENT, _halfExtents.z);
|
||||
}
|
||||
break;
|
||||
case SHAPE_TYPE_COMPOUND:
|
||||
case SHAPE_TYPE_STATIC_MESH:
|
||||
_url = QUrl(url);
|
||||
|
@ -75,9 +79,7 @@ void ShapeInfo::setSphere(float radius) {
|
|||
}
|
||||
|
||||
void ShapeInfo::setPointCollection(const ShapeInfo::PointCollection& pointCollection) {
|
||||
//TODO WL21389: May need to skip resetting type here.
|
||||
_pointCollection = pointCollection;
|
||||
_type = (_pointCollection.size() > 0) ? SHAPE_TYPE_COMPOUND : SHAPE_TYPE_NONE;
|
||||
_doubleHashKey.clear();
|
||||
}
|
||||
|
||||
|
@ -124,7 +126,7 @@ int ShapeInfo::getLargestSubshapePointCount() const {
|
|||
}
|
||||
|
||||
float ShapeInfo::computeVolume() const {
|
||||
//TODO WL21389: Add support for other ShapeTypes( CYLINDER_X, CYLINDER_Y, etc).
|
||||
//TODO WL21389: Add support for other ShapeTypes( CYLINDER_X, CYLINDER_Z, etc).
|
||||
const float DEFAULT_VOLUME = 1.0f;
|
||||
float volume = DEFAULT_VOLUME;
|
||||
switch(_type) {
|
||||
|
|
|
@ -46,7 +46,8 @@ enum ShapeType {
|
|||
SHAPE_TYPE_SIMPLE_HULL,
|
||||
SHAPE_TYPE_SIMPLE_COMPOUND,
|
||||
SHAPE_TYPE_STATIC_MESH,
|
||||
SHAPE_TYPE_ELLIPSOID
|
||||
SHAPE_TYPE_ELLIPSOID,
|
||||
SHAPE_TYPE_CIRCLE
|
||||
};
|
||||
|
||||
class ShapeInfo {
|
||||
|
@ -66,7 +67,7 @@ public:
|
|||
void setCapsuleY(float radius, float halfHeight);
|
||||
void setOffset(const glm::vec3& offset);
|
||||
|
||||
int getType() const { return _type; }
|
||||
ShapeType getType() const { return _type; }
|
||||
|
||||
const glm::vec3& getHalfExtents() const { return _halfExtents; }
|
||||
const glm::vec3& getOffset() const { return _offset; }
|
||||
|
|
|
@ -10,18 +10,18 @@
|
|||
|
||||
gpu::Stream::FormatPointer& getInstancedSolidStreamFormat();
|
||||
|
||||
static const size_t TYPE_COUNT = 4;
|
||||
static const size_t ITEM_COUNT = 50;
|
||||
static const float SHAPE_INTERVAL = (PI * 2.0f) / ITEM_COUNT;
|
||||
static const float ITEM_INTERVAL = SHAPE_INTERVAL / TYPE_COUNT;
|
||||
|
||||
static GeometryCache::Shape SHAPE[TYPE_COUNT] = {
|
||||
static GeometryCache::Shape SHAPE[] = {
|
||||
GeometryCache::Icosahedron,
|
||||
GeometryCache::Cube,
|
||||
GeometryCache::Sphere,
|
||||
GeometryCache::Tetrahedron,
|
||||
};
|
||||
|
||||
static const size_t TYPE_COUNT = (sizeof(SHAPE) / sizeof((SHAPE)[0]));
|
||||
static const size_t ITEM_COUNT = 50;
|
||||
static const float SHAPE_INTERVAL = (PI * 2.0f) / ITEM_COUNT;
|
||||
static const float ITEM_INTERVAL = SHAPE_INTERVAL / TYPE_COUNT;
|
||||
|
||||
const gpu::Element POSITION_ELEMENT { gpu::VEC3, gpu::FLOAT, gpu::XYZ };
|
||||
const gpu::Element NORMAL_ELEMENT { gpu::VEC3, gpu::FLOAT, gpu::XYZ };
|
||||
const gpu::Element COLOR_ELEMENT { gpu::VEC4, gpu::NUINT8, gpu::RGBA };
|
||||
|
@ -34,8 +34,6 @@ TestInstancedShapes::TestInstancedShapes() {
|
|||
static const float ITEM_RADIUS = 20;
|
||||
static const vec3 ITEM_TRANSLATION { 0, 0, -ITEM_RADIUS };
|
||||
for (size_t i = 0; i < TYPE_COUNT; ++i) {
|
||||
GeometryCache::Shape shape = SHAPE[i];
|
||||
GeometryCache::ShapeData shapeData = geometryCache->_shapes[shape];
|
||||
//indirectCommand._count
|
||||
float startingInterval = ITEM_INTERVAL * i;
|
||||
std::vector<mat4> typeTransforms;
|
||||
|
@ -62,7 +60,12 @@ void TestInstancedShapes::renderTest(size_t testId, RenderArgs* args) {
|
|||
batch.setInputFormat(getInstancedSolidStreamFormat());
|
||||
for (size_t i = 0; i < TYPE_COUNT; ++i) {
|
||||
GeometryCache::Shape shape = SHAPE[i];
|
||||
GeometryCache::ShapeData shapeData = geometryCache->_shapes[shape];
|
||||
const GeometryCache::ShapeData *shapeData = geometryCache->getShapeData( shape );
|
||||
if (!shapeData) {
|
||||
|
||||
//--EARLY ITERATION EXIT--( didn't have shape data yet )
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string namedCall = __FUNCTION__ + std::to_string(i);
|
||||
|
||||
|
@ -71,13 +74,13 @@ void TestInstancedShapes::renderTest(size_t testId, RenderArgs* args) {
|
|||
batch.setModelTransform(transforms[i][j]);
|
||||
batch.setupNamedCalls(namedCall, [=](gpu::Batch& batch, gpu::Batch::NamedBatchData&) {
|
||||
batch.setInputBuffer(gpu::Stream::COLOR, gpu::BufferView(colorBuffer, i * ITEM_COUNT * 4, colorBuffer->getSize(), COLOR_ELEMENT));
|
||||
shapeData.drawInstances(batch, ITEM_COUNT);
|
||||
shapeData->drawInstances(batch, ITEM_COUNT);
|
||||
});
|
||||
}
|
||||
|
||||
//for (size_t j = 0; j < ITEM_COUNT; ++j) {
|
||||
// batch.setModelTransform(transforms[j + i * ITEM_COUNT]);
|
||||
// shapeData.draw(batch);
|
||||
// shapeData->draw(batch);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue