From 5b50b362f14dd30b36d9e5aff707b1a0fd1ee622 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Fri, 8 Sep 2017 15:49:18 -0400 Subject: [PATCH] [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 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 --- interface/src/Application.cpp | 5 + interface/src/Util.cpp | 11 ++ interface/src/Util.h | 5 + .../src/RenderableShapeEntityItem.cpp | 27 +--- libraries/entities/src/ShapeEntityItem.cpp | 130 ++++++++++-------- libraries/entities/src/ShapeEntityItem.h | 2 +- libraries/physics/src/ShapeFactory.cpp | 1 + libraries/render-utils/src/GeometryCache.cpp | 81 +++++++++++ libraries/render-utils/src/GeometryCache.h | 18 ++- libraries/shared/src/ShapeInfo.cpp | 8 +- libraries/shared/src/ShapeInfo.h | 5 +- tests/gpu-test/src/TestInstancedShapes.cpp | 25 ++-- 12 files changed, 221 insertions(+), 97 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6e7a405181..87d4db9936 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -120,6 +120,7 @@ #include #include #include +#include #include #include #include @@ -4228,6 +4229,10 @@ void Application::init() { // fire off an immediate domain-server check in now that settings are loaded DependencyManager::get()->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(); diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index 7822b78244..3e3f514117 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -28,6 +28,8 @@ #include #include #include +#include +#include #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); +} + diff --git a/interface/src/Util.h b/interface/src/Util.h index 48acb53936..976a26ce82 100644 --- a/interface/src/Util.h +++ b/interface/src/Util.h @@ -18,6 +18,9 @@ #include #include +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 diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index 7d7de0c08f..a72320fda0 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -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 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::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()->renderWireShape(batch, geometryShape); + geometryCache->renderWireShape(batch, geometryShape); } else { - DependencyManager::get()->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(); 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()->getShapeTriangleCount(geometryShape); + static const auto triCount = geometryCache->getShapeTriangleCount(geometryShape); args->_details._trianglesRendered += (int)triCount; } diff --git a/libraries/entities/src/ShapeEntityItem.cpp b/libraries/entities/src/ShapeEntityItem.cpp index 6f3025881b..655283a601 100644 --- a/libraries/entities/src/ShapeEntityItem.cpp +++ b/libraries/entities/src/ShapeEntityItem.cpp @@ -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; } diff --git a/libraries/entities/src/ShapeEntityItem.h b/libraries/entities/src/ShapeEntityItem.h index 0f8197787b..a88a2098e9 100644 --- a/libraries/entities/src/ShapeEntityItem.h +++ b/libraries/entities/src/ShapeEntityItem.h @@ -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; + using ShapeInfoCalculator = std::function; static void setShapeInfoCalulator(ShapeInfoCalculator callback); ShapeEntityItem(const EntityItemID& entityItemID); diff --git a/libraries/physics/src/ShapeFactory.cpp b/libraries/physics/src/ShapeFactory.cpp index 18dfd2317e..cd0fba848a 100644 --- a/libraries/physics/src/ShapeFactory.cpp +++ b/libraries/physics/src/ShapeFactory.cpp @@ -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); diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index cf8e268681..38994cfa02 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -23,6 +23,7 @@ #include #include +#include #include "TextureCache.h" #include "RenderUtilsLogging.h" @@ -52,6 +53,24 @@ //#define WANT_DEBUG +static std::array 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 &outPointList){ + + if (shapePtr == nullptr){ + //--EARLY EXIT-- + return; + } + + auto geometryCache = DependencyManager::get(); + 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(i); +#if DEBUG_SIMPLE_HULL_POINT_GENERATION + const geometry::Vec &curVert = shapeVerts.get(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 std::vector polygon() { std::vector 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(); // 1 for everyone diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index 5a437cf5e9..867c4bc3ee 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -32,6 +32,7 @@ #include class SimpleProgramKey; +class ShapeEntityItem; typedef QPair Vec2FloatPair; typedef QPair 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 &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; - 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 IntPair; typedef QPair VerticesIndices; + + + VShape _shapes; gpu::PipelinePointer _standardDrawPipeline; gpu::PipelinePointer _standardDrawPipelineNoBlend; diff --git a/libraries/shared/src/ShapeInfo.cpp b/libraries/shared/src/ShapeInfo.cpp index a556548b25..c56b722b61 100644 --- a/libraries/shared/src/ShapeInfo.cpp +++ b/libraries/shared/src/ShapeInfo.cpp @@ -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) { diff --git a/libraries/shared/src/ShapeInfo.h b/libraries/shared/src/ShapeInfo.h index 0ffdf1310d..cab487e07a 100644 --- a/libraries/shared/src/ShapeInfo.h +++ b/libraries/shared/src/ShapeInfo.h @@ -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; } diff --git a/tests/gpu-test/src/TestInstancedShapes.cpp b/tests/gpu-test/src/TestInstancedShapes.cpp index 6a98ee58b9..da50f8521f 100644 --- a/tests/gpu-test/src/TestInstancedShapes.cpp +++ b/tests/gpu-test/src/TestInstancedShapes.cpp @@ -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 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); //} } }