-
Notifications
You must be signed in to change notification settings - Fork 67
Obb calculation with debug draw #975
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
@kevyuu link to old PR in description |
| class COBBGenerator | ||
| { | ||
| public: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indentation
| using FetchFn = std::function<hlsl::float32_t3(size_t vertexIndex)>; | ||
| FetchFn fetch; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is always runtime polymorphic (wont specialize nicely based on a lambda), VertexCollection should be templated, the default template arg can be std::function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw I don't think all the OBB stuff should be nested inside CPolygonGeometryManipulator
| static auto fromSpan(std::span<const hlsl::float32_t3> vertices) -> VertexCollection | ||
| { | ||
| return VertexCollection{ | ||
| .fetch = [data = vertices.data()](size_t vertexIndex)-> hlsl::float32_t3 | ||
| { | ||
| return data[vertexIndex]; | ||
| }, | ||
| .size = vertices.size() | ||
| }; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be a different template instantiation of VertexCollection
| point_t mid; | ||
| std::array<point_t, D> axes; | ||
| point_t ext; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use a matrix<float32_t,D,D+1> instead
@karimsayedre which OBB is more useful for you in general, the one that transforms a [0,1]^3 or [-1,1]^3 obb ?
| // | ||
| core::smart_refctd_ptr<ICPUMeshBuffer> IMeshManipulator::calculateSmoothNormals(ICPUMeshBuffer* inbuffer, bool makeNewMesh, float epsilon, uint32_t normalAttrID, VxCmpFunction vxcmp) | ||
| { | ||
| if (inbuffer == nullptr) | ||
| { | ||
| _NBL_DEBUG_BREAK_IF(true); | ||
| return nullptr; | ||
| } | ||
|
|
||
| //Mesh has to have unique primitives | ||
| if (inbuffer->getIndexType() != E_INDEX_TYPE::EIT_UNKNOWN) | ||
| { | ||
| _NBL_DEBUG_BREAK_IF(true); | ||
| return nullptr; | ||
| } | ||
|
|
||
| core::smart_refctd_ptr<ICPUMeshBuffer> outbuffer; | ||
| if (makeNewMesh) | ||
| { | ||
| outbuffer = core::move_and_static_cast<ICPUMeshBuffer>(inbuffer->clone(0u)); | ||
|
|
||
| const auto normalAttr = inbuffer->getNormalAttributeIx(); | ||
| auto normalBinding = inbuffer->getBindingNumForAttribute(normalAttr); | ||
| const auto oldPipeline = inbuffer->getPipeline(); | ||
| auto vertexParams = oldPipeline->getCachedCreationParams().vertexInput; | ||
| bool notUniqueBinding = false; | ||
| for (uint16_t attr=0u; attr<SVertexInputParams::MAX_VERTEX_ATTRIB_COUNT; attr++) | ||
| if (attr!=normalAttr && (vertexParams.enabledAttribFlags&(0x1u<<attr))!=0u && vertexParams.attributes[attr].binding==normalBinding) | ||
| notUniqueBinding = true; | ||
| if (notUniqueBinding) | ||
| { | ||
| int32_t firstBindingNotUsed = hlsl::findLSB(vertexParams.enabledBindingFlags^0xffffu); | ||
| assert(firstBindingNotUsed>0 && firstBindingNotUsed<SVertexInputParams::MAX_ATTR_BUF_BINDING_COUNT); | ||
| normalBinding = static_cast<uint32_t>(firstBindingNotUsed); | ||
|
|
||
| vertexParams.attributes[normalAttr].binding = normalBinding; | ||
| vertexParams.enabledBindingFlags |= 0x1u<<normalBinding; | ||
| } | ||
|
|
||
| const auto normalFormatBytesize = asset::getTexelOrBlockBytesize(inbuffer->getAttribFormat(normalAttr)); | ||
| auto normalBuf = ICPUBuffer::create({ normalFormatBytesize*IMeshManipulator::upperBoundVertexID(inbuffer) }); | ||
| outbuffer->setVertexBufferBinding({0ull,std::move(normalBuf)},normalBinding); | ||
|
|
||
| auto pipeline = core::move_and_static_cast<ICPURenderpassIndependentPipeline>(oldPipeline->clone(0u)); | ||
| vertexParams.bindings[normalBinding].stride = normalFormatBytesize; | ||
| vertexParams.attributes[normalAttr].relativeOffset = 0u; | ||
| pipeline->getCachedCreationParams().vertexInput = vertexParams; | ||
| outbuffer->setPipeline(std::move(pipeline)); | ||
| } | ||
| else | ||
| outbuffer = core::smart_refctd_ptr<ICPUMeshBuffer>(inbuffer); | ||
| CSmoothNormalGenerator::calculateNormals(outbuffer.get(), epsilon, normalAttrID, vxcmp); | ||
|
|
||
| return outbuffer; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can delete this because we've reimplemented
| // Used by createMeshBufferWelded only | ||
| static bool cmpVertices(ICPUMeshBuffer* _inbuf, const void* _va, const void* _vb, size_t _vsize, const IMeshManipulator::SErrorMetric* _errMetrics) | ||
| { | ||
| auto cmpInteger = [](uint32_t* _a, uint32_t* _b, size_t _n) -> bool { | ||
| return !memcmp(_a, _b, _n*4); | ||
| }; | ||
|
|
||
| constexpr uint32_t MAX_ATTRIBS = ICPUMeshBuffer::MAX_VERTEX_ATTRIB_COUNT; | ||
|
|
||
| const uint8_t* va = reinterpret_cast<const uint8_t*>(_va), *vb = reinterpret_cast<const uint8_t*>(_vb); | ||
| for (size_t i = 0u; i < MAX_ATTRIBS; ++i) | ||
| { | ||
| if (!_inbuf->isAttributeEnabled(i)) | ||
| continue; | ||
|
|
||
| const auto atype = _inbuf->getAttribFormat(i); | ||
| const auto cpa = getFormatChannelCount(atype); | ||
|
|
||
| if (isIntegerFormat(atype) || isScaledFormat(atype)) | ||
| { | ||
| uint32_t attr[8]; | ||
| ICPUMeshBuffer::getAttribute(attr, va, atype); | ||
| ICPUMeshBuffer::getAttribute(attr+4, vb, atype); | ||
| if (!cmpInteger(attr, attr+4, cpa)) | ||
| return false; | ||
| } | ||
| else | ||
| { | ||
| core::vectorSIMDf attr[2]; | ||
| ICPUMeshBuffer::getAttribute(attr[0], va, atype); | ||
| ICPUMeshBuffer::getAttribute(attr[1], vb, atype); | ||
| if (!IMeshManipulator::compareFloatingPointAttribute(attr[0], attr[1], cpa, _errMetrics[i])) | ||
| return false; | ||
| } | ||
|
|
||
| const uint32_t sz = getTexelOrBlockBytesize(atype); | ||
| va += sz; | ||
| vb += sz; | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| //! Creates a copy of a mesh, which will have identical vertices welded together | ||
| core::smart_refctd_ptr<ICPUMeshBuffer> IMeshManipulator::createMeshBufferWelded(ICPUMeshBuffer *inbuffer, const SErrorMetric* _errMetrics, const bool& optimIndexType, const bool& makeNewMesh) | ||
| { | ||
| if (!inbuffer || !inbuffer->getPipeline()) | ||
| return nullptr; | ||
|
|
||
| constexpr uint32_t MAX_ATTRIBS = ICPUMeshBuffer::MAX_VERTEX_ATTRIB_COUNT; | ||
|
|
||
| bool bufferPresent[MAX_ATTRIBS]; | ||
|
|
||
| size_t vertexAttrSize[MAX_ATTRIBS]; | ||
| size_t vertexSize = 0; | ||
| for (size_t i=0; i<MAX_ATTRIBS; i++) | ||
| { | ||
| const auto& buf = inbuffer->getAttribBoundBuffer(i).buffer; | ||
| bufferPresent[i] = inbuffer->isAttributeEnabled(i); | ||
| if (bufferPresent[i] && buf) | ||
| { | ||
| const E_FORMAT componentType = inbuffer->getAttribFormat(i); | ||
| vertexAttrSize[i] = getTexelOrBlockBytesize(componentType); | ||
| vertexSize += vertexAttrSize[i]; | ||
| } | ||
| } | ||
|
|
||
| auto cmpfunc = [&, inbuffer, vertexSize, _errMetrics](const void* _va, const void* _vb) { | ||
| return cmpVertices(inbuffer, _va, _vb, vertexSize, _errMetrics); | ||
| }; | ||
|
|
||
| const uint32_t vertexCount = IMeshManipulator::upperBoundVertexID(inbuffer); | ||
| const E_INDEX_TYPE oldIndexType = inbuffer->getIndexType(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can delete this because we've reimplemented
| float IMeshManipulator::DistanceToLine(core::vectorSIMDf P0, core::vectorSIMDf P1, core::vectorSIMDf InPoint) | ||
| { | ||
| core::vectorSIMDf PointToStart = InPoint - P0; | ||
| core::vectorSIMDf Diff = core::cross(P0 - P1, PointToStart); | ||
|
|
||
| return core::dot(Diff, Diff).x; | ||
| } | ||
|
|
||
| float IMeshManipulator::DistanceToPlane(core::vectorSIMDf InPoint, core::vectorSIMDf PlanePoint, core::vectorSIMDf PlaneNormal) | ||
| { | ||
| core::vectorSIMDf PointToPlane = InPoint - PlanePoint; | ||
|
|
||
| return (core::dot(PointToPlane, PlaneNormal).x >= 0) ? core::abs(core::dot(PointToPlane, PlaneNormal).x) : 0; | ||
| } | ||
|
|
||
| core::matrix3x4SIMD IMeshManipulator::calculateOBB(const nbl::asset::ICPUMeshBuffer* meshbuffer) | ||
| { | ||
| auto FindMinMaxProj = [&](const core::vectorSIMDf& Dir, const core::vectorSIMDf Extrema[]) -> core::vectorSIMDf | ||
| { | ||
| float MinPoint, MaxPoint; | ||
| MinPoint = MaxPoint = core::dot(Dir, Extrema[0]).x; | ||
|
|
||
| for (int i = 1; i < 12; i++) { | ||
| float Proj = core::dot(Dir, Extrema[i]).x; | ||
| if (MinPoint > Proj) MinPoint = Proj; | ||
| if (MaxPoint < Proj) MaxPoint = Proj; | ||
| } | ||
|
|
||
| return core::vectorSIMDf(MaxPoint, MinPoint, 0); | ||
| }; | ||
|
|
||
| auto ComputeAxis = [&](const core::vectorSIMDf& P0, const core::vectorSIMDf& P1, const core::vectorSIMDf& P2, core::vectorSIMDf* AxesEdge, float& PrevQuality, const core::vectorSIMDf Extrema[]) -> void | ||
| { | ||
| core::vectorSIMDf e0 = P1 - P0; | ||
| core::vectorSIMDf Edges[3]; | ||
| Edges[0] = e0 / core::length(e0); | ||
| Edges[1] = core::cross(P2 - P1, P1 - P0); | ||
| Edges[1] = Edges[1] / core::length(Edges[1]); | ||
| Edges[2] = core::cross(Edges[0], Edges[1]); | ||
|
|
||
| core::vectorSIMDf Edge10Proj = FindMinMaxProj(Edges[0], Extrema); | ||
| core::vectorSIMDf Edge20Proj = FindMinMaxProj(Edges[1], Extrema); | ||
| core::vectorSIMDf Edge30Proj = FindMinMaxProj(Edges[2], Extrema); | ||
| core::vectorSIMDf Max2 = core::vectorSIMDf(Edge10Proj.x, Edge20Proj.x, Edge30Proj.x); | ||
| core::vectorSIMDf Min2 = core::vectorSIMDf(Edge10Proj.y, Edge20Proj.y, Edge30Proj.y); | ||
| core::vectorSIMDf Diff = Max2 - Min2; | ||
| float Quality = Diff.x * Diff.y + Diff.x * Diff.z + Diff.y * Diff.z; | ||
|
|
||
| if (Quality < PrevQuality) { | ||
| PrevQuality = Quality; | ||
| for (int i = 0; i < 3; i++) { | ||
| AxesEdge[i] = Edges[i]; | ||
| } | ||
| } | ||
| }; | ||
|
|
||
| core::vectorSIMDf Extrema[12]; | ||
| float A = (core::sqrt(5.0f) - 1.0f) / 2.0f; | ||
| core::vectorSIMDf N[6]; | ||
| N[0] = core::vectorSIMDf(0, 1, A); | ||
| N[1] = core::vectorSIMDf(0, 1, -A); | ||
| N[2] = core::vectorSIMDf(1, A, 0); | ||
| N[3] = core::vectorSIMDf(1, -A, 0); | ||
| N[4] = core::vectorSIMDf(A, 0, 1); | ||
| N[5] = core::vectorSIMDf(A, 0, -1); | ||
| float Bs[12]; | ||
| float B; | ||
| int indexcount = meshbuffer->getIndexCount(); | ||
| core::vectorSIMDf CachedVertex = meshbuffer->getPosition(meshbuffer->getIndexValue(0)); | ||
| core::vectorSIMDf AABBMax = CachedVertex; | ||
| core::vectorSIMDf AABBMin = CachedVertex; | ||
| for (int k = 0; k < 12; k += 2) { | ||
| B = core::dot(N[k / 2], CachedVertex).x; | ||
| Extrema[k] = core::vectorSIMDf(CachedVertex.x, CachedVertex.y, CachedVertex.z); Bs[k] = B; | ||
| Extrema[k + 1] = core::vectorSIMDf(CachedVertex.x, CachedVertex.y, CachedVertex.z); Bs[k + 1] = B; | ||
| } | ||
| for (uint32_t j = 1u; j < indexcount; j += 1u) { | ||
| CachedVertex = meshbuffer->getPosition(meshbuffer->getIndexValue(j)); | ||
| for (int k = 0; k < 12; k += 2) { | ||
| B = core::dot(N[k / 2], CachedVertex).x; | ||
| if (B > Bs[k] || j == 0) { Extrema[k] = core::vectorSIMDf(CachedVertex.x, CachedVertex.y, CachedVertex.z); Bs[k] = B; } | ||
| if (B < Bs[k + 1] || j == 0) { Extrema[k + 1] = core::vectorSIMDf(CachedVertex.x, CachedVertex.y, CachedVertex.z); Bs[k + 1] = B; } | ||
| } | ||
| AABBMax = core::max(AABBMax, CachedVertex); | ||
| AABBMin = core::min(AABBMin, CachedVertex); | ||
| } | ||
|
|
||
| int LBTE1 = -1; | ||
| float MaxDiff = 0; | ||
| for (int i = 0; i < 12; i += 2) { | ||
| core::vectorSIMDf C = (Extrema[i]) - (Extrema[i + 1]); float TempDiff = core::dot(C, C).x; if (TempDiff > MaxDiff) { MaxDiff = TempDiff; LBTE1 = i; } | ||
| } | ||
| assert(LBTE1 != -1); | ||
|
|
||
| core::vectorSIMDf P0 = Extrema[LBTE1]; | ||
| core::vectorSIMDf P1 = Extrema[LBTE1 + 1]; | ||
|
|
||
| int LBTE3 = 0; | ||
| float MaxDist = 0; | ||
| int RemoveAt = 0; | ||
|
|
||
| for (int i = 0; i < 10; i++) { | ||
| int index = i; | ||
| if (index >= LBTE1) index += 2; | ||
| float TempDist = DistanceToLine(P0, P1, core::vectorSIMDf(Extrema[index].x, Extrema[index].y, Extrema[index].z)); | ||
| if (TempDist > MaxDist || i == 0) { | ||
| MaxDist = TempDist; | ||
| LBTE3 = index; | ||
| RemoveAt = i; | ||
| } | ||
| } | ||
|
|
||
| core::vectorSIMDf P2 = Extrema[LBTE3]; | ||
| core::vectorSIMDf ExtremaRemainingTemp[9]; | ||
| for (int i = 0; i < 9; i++) { | ||
| int index = i; | ||
| if (index >= RemoveAt) index += 1; | ||
| if (index >= LBTE1) index += 2; | ||
| ExtremaRemainingTemp[i] = core::vectorSIMDf(Extrema[index].x, Extrema[index].y, Extrema[index].z, index); | ||
| } | ||
|
|
||
| float MaxDistPlane = -9999999.0f; | ||
| float MinDistPlane = -9999999.0f; | ||
| float TempDistPlane = 0; | ||
| core::vectorSIMDf Q0 = core::vectorSIMDf(0, 0, 0); | ||
| core::vectorSIMDf Q1 = core::vectorSIMDf(0, 0, 0); | ||
| core::vectorSIMDf Norm = core::cross(P2 - P1, P2 - P0); | ||
| Norm /= core::length(Norm); | ||
| for (int i = 0; i < 9; i++) { | ||
| TempDistPlane = DistanceToPlane(core::vectorSIMDf(ExtremaRemainingTemp[i].x, ExtremaRemainingTemp[i].y, ExtremaRemainingTemp[i].z), P0, Norm); | ||
| if (TempDistPlane > MaxDistPlane || i == 0) { | ||
| MaxDistPlane = TempDistPlane; | ||
| Q0 = Extrema[(int)ExtremaRemainingTemp[i].w]; | ||
| } | ||
| TempDistPlane = DistanceToPlane(core::vectorSIMDf(ExtremaRemainingTemp[i].x, ExtremaRemainingTemp[i].y, ExtremaRemainingTemp[i].z), P0, -Norm); | ||
| if (TempDistPlane > MinDistPlane || i == 0) { | ||
| MinDistPlane = TempDistPlane; | ||
| Q1 = Extrema[(int)ExtremaRemainingTemp[i].w]; | ||
| } | ||
| } | ||
|
|
||
| float BestQuality = 99999999999999.0f; | ||
| core::vectorSIMDf BestAxis[3]; | ||
| ComputeAxis(P0, P1, P2, BestAxis, BestQuality, Extrema); | ||
| ComputeAxis(P2, P0, P1, BestAxis, BestQuality, Extrema); | ||
| ComputeAxis(P1, P2, P0, BestAxis, BestQuality, Extrema); | ||
|
|
||
| ComputeAxis(P1, Q0, P0, BestAxis, BestQuality, Extrema); | ||
| ComputeAxis(P0, P1, Q0, BestAxis, BestQuality, Extrema); | ||
| ComputeAxis(Q0, P0, P1, BestAxis, BestQuality, Extrema); | ||
|
|
||
| ComputeAxis(P2, Q0, P0, BestAxis, BestQuality, Extrema); | ||
| ComputeAxis(P0, P2, Q0, BestAxis, BestQuality, Extrema); | ||
| ComputeAxis(Q0, P0, P2, BestAxis, BestQuality, Extrema); | ||
|
|
||
| ComputeAxis(P1, Q0, P2, BestAxis, BestQuality, Extrema); | ||
| ComputeAxis(P2, P1, Q0, BestAxis, BestQuality, Extrema); | ||
| ComputeAxis(Q0, P2, P1, BestAxis, BestQuality, Extrema); | ||
|
|
||
| ComputeAxis(P1, Q1, P0, BestAxis, BestQuality, Extrema); | ||
| ComputeAxis(P0, P1, Q1, BestAxis, BestQuality, Extrema); | ||
| ComputeAxis(Q1, P0, P1, BestAxis, BestQuality, Extrema); | ||
|
|
||
| ComputeAxis(P2, Q1, P0, BestAxis, BestQuality, Extrema); | ||
| ComputeAxis(P0, P2, Q1, BestAxis, BestQuality, Extrema); | ||
| ComputeAxis(Q1, P0, P2, BestAxis, BestQuality, Extrema); | ||
|
|
||
| ComputeAxis(P1, Q1, P2, BestAxis, BestQuality, Extrema); | ||
| ComputeAxis(P2, P1, Q1, BestAxis, BestQuality, Extrema); | ||
| ComputeAxis(Q1, P2, P1, BestAxis, BestQuality, Extrema); | ||
|
|
||
| core::matrix3x4SIMD TransMat = core::matrix3x4SIMD( | ||
| BestAxis[0].x, BestAxis[1].x, BestAxis[2].x, 0, | ||
| BestAxis[0].y, BestAxis[1].y, BestAxis[2].y, 0, | ||
| BestAxis[0].z, BestAxis[1].z, BestAxis[2].z, 0); | ||
|
|
||
| core::vectorSIMDf MinPoint; | ||
| core::vectorSIMDf MaxPoint; | ||
| CachedVertex = meshbuffer->getPosition(meshbuffer->getIndexValue(0)); | ||
| MinPoint = core::vectorSIMDf(core::dot(BestAxis[0], CachedVertex).x, core::dot(BestAxis[1], CachedVertex).x, core::dot(BestAxis[2], CachedVertex).x); | ||
| MaxPoint = MinPoint; | ||
| for (uint32_t j = 1u; j < indexcount; j += 1u) | ||
| { | ||
| CachedVertex = meshbuffer->getPosition(meshbuffer->getIndexValue(j)); | ||
| core::vectorSIMDf Proj = core::vectorSIMDf(core::dot(BestAxis[0], CachedVertex).x, core::dot(BestAxis[1], CachedVertex).x, core::dot(BestAxis[2], CachedVertex).x); | ||
| MinPoint = core::min(MinPoint, Proj); | ||
| MaxPoint = core::max(MaxPoint, Proj); | ||
| } | ||
|
|
||
| core::vectorSIMDf OBBDiff = MaxPoint - MinPoint; | ||
| float OBBQuality = OBBDiff.x * OBBDiff.y + OBBDiff.y * OBBDiff.z + OBBDiff.z * OBBDiff.x; | ||
|
|
||
| core::vectorSIMDf ABBDiff = AABBMax - AABBMin; | ||
| float ABBQuality = ABBDiff.x * ABBDiff.y + ABBDiff.y * ABBDiff.z + ABBDiff.z * ABBDiff.x; | ||
| core::matrix3x4SIMD scaleMat; | ||
| core::matrix3x4SIMD translationMat; | ||
| translationMat.setTranslation(-(MinPoint) / OBBDiff); | ||
| scaleMat.setScale(OBBDiff); | ||
| TransMat = core::concatenateBFollowedByA(TransMat, scaleMat); | ||
| TransMat = core::concatenateBFollowedByA(TransMat, translationMat); | ||
| if (ABBQuality < OBBQuality) { | ||
| translationMat.setTranslation(-(AABBMin) / ABBDiff); | ||
| scaleMat.setScale(ABBDiff); | ||
| TransMat = core::matrix3x4SIMD( | ||
| 1, 0, 0, 0, | ||
| 0, 1, 0, 0, | ||
| 0, 0, 1, 0); | ||
| TransMat = core::concatenateBFollowedByA(TransMat, scaleMat); | ||
| TransMat = core::concatenateBFollowedByA(TransMat, translationMat); | ||
| } | ||
|
|
||
| return TransMat; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AnastaZIuk old code
| hlsl::shapes::OBB<> COBBGenerator::compute(const VertexCollection& vertices) | ||
| { | ||
| constexpr size_t SAMPLE_DIR_COUNT = 7; // Number of sample directions | ||
| constexpr size_t SAMPLE_COUNT = SAMPLE_DIR_COUNT * 2; | ||
|
|
||
| if (vertices.size <= 0) | ||
| { | ||
| return hlsl::shapes::OBB<>::createAxisAligned({}, {}); | ||
| } | ||
|
|
||
| static auto getQualityValue = [](hlsl::float32_t3 len) -> hlsl::float32_t | ||
| { | ||
| return len.x * len.y + len.x * len.z + len.y * len.z; //half box area | ||
| }; | ||
|
|
||
| using ExtremalVertices = Extremals<hlsl::float32_t3, SAMPLE_DIR_COUNT>; | ||
| using ExtremalProjections = Extremals<hlsl::float32_t, SAMPLE_DIR_COUNT>; | ||
| using Axes = std::array<hlsl::float32_t3, 3>; | ||
| using Edges = std::array<hlsl::float32_t3, 3>; | ||
|
|
||
| struct ExtremalSamples |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AnastaZIuk new code
| hlsl::shapes::OBB<> CPolygonGeometryManipulator::calculateOBB(const VertexCollection& vertices) | ||
| { | ||
| return COBBGenerator::compute(vertices); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can be inline, or actually why is anything to do with OBBs in CpolygonGeometryManitpulator ?
COBBGenerator can be completely separate (also it works on anything that has vertices which can be turned into a convex hull of an object.
Description
Obb calculation using DiTO-14
Testing
Using an example demo pull request