mirror of https://github.com/bkaradzic/bgfx
Added topology convert utility function.
This commit is contained in:
parent
6fd77942ac
commit
de08904b62
|
@ -20,4 +20,5 @@
|
|||
#include "shader_dxbc.cpp"
|
||||
#include "shader_dx9bc.cpp"
|
||||
#include "shader_spirv.cpp"
|
||||
#include "topology.cpp"
|
||||
#include "vertexdecl.cpp"
|
||||
|
|
|
@ -0,0 +1,215 @@
|
|||
/*
|
||||
* Copyright 2011-2016 Branimir Karadzic. All rights reserved.
|
||||
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
|
||||
*/
|
||||
|
||||
#include <bx/debug.h>
|
||||
#include <bx/radixsort.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "topology.h"
|
||||
|
||||
namespace bgfx
|
||||
{
|
||||
template<typename IndexT>
|
||||
static uint32_t toplogyConvertTriListFlipWinding(void* _dst, uint32_t _dstSize, const IndexT* _indices, uint32_t _numIndices)
|
||||
{
|
||||
if (NULL == _dst)
|
||||
{
|
||||
return _numIndices;
|
||||
}
|
||||
|
||||
IndexT* dst = (IndexT*)_dst;
|
||||
IndexT* end = &dst[_dstSize/sizeof(IndexT)];
|
||||
for (uint32_t ii = 0; ii < _numIndices && dst < end; ii += 3, dst += 3)
|
||||
{
|
||||
const IndexT* tri = &_indices[ii];
|
||||
IndexT i0 = tri[0], i1 = tri[1], i2 = tri[2];
|
||||
|
||||
dst[0] = i0;
|
||||
dst[1] = i2;
|
||||
dst[2] = i1;
|
||||
}
|
||||
|
||||
return _numIndices;
|
||||
}
|
||||
|
||||
template<typename IndexT, typename SortT>
|
||||
static uint32_t toplogyConvertTriListToLineList(void* _dst, uint32_t _dstSize, const IndexT* _indices, uint32_t _numIndices, IndexT* _temp, SortT* _tempSort)
|
||||
{
|
||||
// Create all line pairs and sort indices.
|
||||
IndexT* dst = _temp;
|
||||
for (uint32_t ii = 0; ii < _numIndices; ii += 3)
|
||||
{
|
||||
const IndexT* tri = &_indices[ii];
|
||||
IndexT i0 = tri[0], i1 = tri[1], i2 = tri[2];
|
||||
|
||||
if (i0 > i1) { bx::xchg(i0, i1); }
|
||||
if (i1 > i2) { bx::xchg(i1, i2); }
|
||||
if (i0 > i1) { bx::xchg(i0, i1); }
|
||||
BX_CHECK(i0 < i1 < i2, "");
|
||||
|
||||
dst[0] = i0; dst[1] = i1;
|
||||
dst[2] = i1; dst[3] = i2;
|
||||
dst[4] = i0; dst[5] = i2;
|
||||
dst += 6;
|
||||
}
|
||||
|
||||
// Sort all line pairs.
|
||||
SortT* sorted = (SortT*)_temp;
|
||||
bx::radixSort(sorted, _tempSort, _numIndices);
|
||||
|
||||
uint32_t num = 0;
|
||||
|
||||
// Remove all line pair duplicates.
|
||||
if (NULL == _dst)
|
||||
{
|
||||
SortT last = sorted[0];
|
||||
for (uint32_t ii = 1; ii < _numIndices; ++ii)
|
||||
{
|
||||
if (last != sorted[ii])
|
||||
{
|
||||
num += 2;
|
||||
last = sorted[ii];
|
||||
}
|
||||
}
|
||||
num += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst = (IndexT*)_dst;
|
||||
IndexT* end = &dst[_dstSize/sizeof(IndexT)];
|
||||
SortT last = sorted[0];
|
||||
for (uint32_t ii = 1; ii < _numIndices && dst < end; ++ii)
|
||||
{
|
||||
if (last != sorted[ii])
|
||||
{
|
||||
union Un { SortT key; struct { IndexT i0; IndexT i1; } u16; } un = { last };
|
||||
dst[0] = un.u16.i0;
|
||||
dst[1] = un.u16.i1;
|
||||
dst += 2;
|
||||
last = sorted[ii];
|
||||
}
|
||||
}
|
||||
|
||||
if (dst < end)
|
||||
{
|
||||
union Un { SortT key; struct { IndexT i0; IndexT i1; } u16; } un = { last };
|
||||
dst[0] = un.u16.i0;
|
||||
dst[1] = un.u16.i1;
|
||||
dst += 2;
|
||||
}
|
||||
|
||||
num = uint32_t(dst - (IndexT*)_dst);
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
template<typename IndexT, typename SortT>
|
||||
static uint32_t toplogyConvertTriListToLineList(void* _dst, uint32_t _dstSize, const IndexT* _indices, uint32_t _numIndices, bx::AllocatorI* _allocator)
|
||||
{
|
||||
IndexT* temp = (IndexT*)BX_ALLOC(_allocator, _numIndices*2*sizeof(IndexT)*2);
|
||||
SortT* tempSort = (SortT*)&temp[_numIndices*2];
|
||||
uint32_t num = toplogyConvertTriListToLineList(_dst, _dstSize, _indices, _numIndices, temp, tempSort);
|
||||
BX_FREE(_allocator, temp);
|
||||
return num;
|
||||
}
|
||||
|
||||
template<typename IndexT>
|
||||
static uint32_t toplogyConvertTriStripToTriList(void* _dst, uint32_t _dstSize, const IndexT* _indices, uint32_t _numIndices)
|
||||
{
|
||||
IndexT* dst = (IndexT*)_dst;
|
||||
IndexT* end = &dst[_dstSize/sizeof(IndexT)];
|
||||
|
||||
for (uint32_t ii = 0, num = _numIndices-2; ii < num && dst < end; ++ii)
|
||||
{
|
||||
IndexT i0 = _indices[ii+0];
|
||||
IndexT i1 = _indices[ii+1];
|
||||
IndexT i2 = _indices[ii+2];
|
||||
if (i0 != i1
|
||||
&& i1 != i2)
|
||||
{
|
||||
dst[0] = i0;
|
||||
dst[1] = i1;
|
||||
dst[2] = i2;
|
||||
dst += 3;
|
||||
}
|
||||
}
|
||||
|
||||
return uint32_t(dst - (IndexT*)_dst);
|
||||
}
|
||||
|
||||
template<typename IndexT>
|
||||
static uint32_t toplogyConvertLineStripToLineList(void* _dst, uint32_t _dstSize, const IndexT* _indices, uint32_t _numIndices)
|
||||
{
|
||||
IndexT* dst = (IndexT*)_dst;
|
||||
IndexT* end = &dst[_dstSize/sizeof(IndexT)];
|
||||
|
||||
IndexT i0 = _indices[0];
|
||||
|
||||
for (uint32_t ii = 1; ii < _numIndices && dst < end; ++ii)
|
||||
{
|
||||
IndexT i1 = _indices[ii];
|
||||
if (i0 != i1)
|
||||
{
|
||||
dst[0] = i0;
|
||||
dst[1] = i1;
|
||||
dst += 2;
|
||||
|
||||
i0 = i1;
|
||||
}
|
||||
}
|
||||
|
||||
return uint32_t(dst - (IndexT*)_dst);
|
||||
}
|
||||
|
||||
uint32_t toplogyConvert(TopologyConvert::Enum _conversion, void* _dst, uint32_t _dstSize, const void* _indices, uint32_t _numIndices, bool _index32, bx::AllocatorI* _allocator)
|
||||
{
|
||||
switch (_conversion)
|
||||
{
|
||||
case TopologyConvert::TriStripToTriList:
|
||||
if (_index32)
|
||||
{
|
||||
return toplogyConvertTriStripToTriList(_dst, _dstSize, (const uint32_t*)_indices, _numIndices);
|
||||
}
|
||||
|
||||
return toplogyConvertTriStripToTriList(_dst, _dstSize, (const uint16_t*)_indices, _numIndices);
|
||||
|
||||
case TopologyConvert::TriListFlipWinding:
|
||||
if (_index32)
|
||||
{
|
||||
return toplogyConvertTriListFlipWinding(_dst, _dstSize, (const uint32_t*)_indices, _numIndices);
|
||||
}
|
||||
|
||||
return toplogyConvertTriListFlipWinding(_dst, _dstSize, (const uint16_t*)_indices, _numIndices);
|
||||
|
||||
case TopologyConvert::TriListToLineList:
|
||||
if (NULL == _allocator)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (_index32)
|
||||
{
|
||||
return toplogyConvertTriListToLineList<uint32_t, uint64_t>(_dst, _dstSize, (const uint32_t*)_indices, _numIndices, _allocator);
|
||||
}
|
||||
|
||||
return toplogyConvertTriListToLineList<uint16_t, uint32_t>(_dst, _dstSize, (const uint16_t*)_indices, _numIndices, _allocator);
|
||||
|
||||
case TopologyConvert::LineStripToLineList:
|
||||
if (_index32)
|
||||
{
|
||||
return toplogyConvertLineStripToLineList(_dst, _dstSize, (const uint32_t*)_indices, _numIndices);
|
||||
}
|
||||
|
||||
return toplogyConvertLineStripToLineList(_dst, _dstSize, (const uint16_t*)_indices, _numIndices);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} //namespace bgfx
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright 2011-2016 Branimir Karadzic. All rights reserved.
|
||||
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
|
||||
*/
|
||||
|
||||
#ifndef BGFX_TOPOLOGY_H_HEADER_GUARD
|
||||
#define BGFX_TOPOLOGY_H_HEADER_GUARD
|
||||
|
||||
#include <bgfx/bgfx.h>
|
||||
#include <bx/allocator.h>
|
||||
|
||||
namespace bgfx
|
||||
{
|
||||
///
|
||||
struct TopologyConvert
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
TriListFlipWinding,
|
||||
TriListToLineList,
|
||||
TriStripToTriList,
|
||||
LineStripToLineList,
|
||||
|
||||
Count
|
||||
};
|
||||
};
|
||||
|
||||
/// Converts topology from triangle list to line list.
|
||||
///
|
||||
/// @param[in] _conversion
|
||||
/// @param[in] _dst
|
||||
/// @param[in] _dstSize
|
||||
/// @param[in] _indices
|
||||
/// @param[in] _numIndices
|
||||
/// @param[in] _index32
|
||||
///
|
||||
/// @returns
|
||||
///
|
||||
uint32_t toplogyConvert(TopologyConvert::Enum _conversion, void* _dst, uint32_t _dstSize, const void* _indices, uint32_t _numIndices, bool _index32, bx::AllocatorI* _allocator);
|
||||
|
||||
} // namespace bgfx
|
||||
|
||||
#endif // BGFX_TOPOLOGY_H_HEADER_GUARD
|
Loading…
Reference in New Issue