diff --git a/Demos/GimpactTestDemo/Jamfile b/Demos/GimpactTestDemo/Jamfile index 6145c8bb4..7b614be6d 100644 --- a/Demos/GimpactTestDemo/Jamfile +++ b/Demos/GimpactTestDemo/Jamfile @@ -15,7 +15,9 @@ SubDir TOP Demos GimpactTestDemo ; MsvcIncDirs $(<) : "../../Demos/OpenGL" - "../../Extras/GIMPACT/include" ; + "../../Extras/GIMPACT/include" + "../../Extras/GIMPACTUtils" + ; } ExtraDemo1 GimpactTestDemo : [ Wildcard *.h *.cpp ] ; diff --git a/Extras/GIMPACT/include/GIMPACT/Bullet/btGenericPoolAllocator.h b/Extras/GIMPACT/include/GIMPACT/Bullet/btGenericPoolAllocator.h new file mode 100755 index 000000000..414664dd3 --- /dev/null +++ b/Extras/GIMPACT/include/GIMPACT/Bullet/btGenericPoolAllocator.h @@ -0,0 +1,168 @@ +/*! \file btGenericPoolAllocator.h +\author Francisco León Nájera. email projectileman@yahoo.com + +General purpose allocator class +*/ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_GENERIC_POOL_ALLOCATOR_H +#define BT_GENERIC_POOL_ALLOCATOR_H + +#include +#include +#include +#include "LinearMath/btAlignedAllocator.h" + +#define BT_UINT_MAX UINT_MAX +#define BT_DEFAULT_MAX_POOLS 16 + + +//! Generic Pool class +class btGenericMemoryPool +{ +public: + unsigned char * m_pool; //[m_element_size*m_max_element_count]; + size_t * m_free_nodes; //[m_max_element_count];//! free nodes + size_t * m_allocated_sizes;//[m_max_element_count];//! Number of elements allocated per node + size_t m_allocated_count; + size_t m_free_nodes_count; +protected: + size_t m_element_size; + size_t m_max_element_count; + + size_t allocate_from_free_nodes(size_t num_elements); + size_t allocate_from_pool(size_t num_elements); + +public: + + void init_pool(size_t element_size, size_t element_count); + + void end_pool(); + + + btGenericMemoryPool(size_t element_size, size_t element_count) + { + init_pool(element_size, element_count); + } + + ~btGenericMemoryPool() + { + end_pool(); + } + + + inline size_t get_pool_capacity() + { + return m_element_size*m_max_element_count; + } + + inline size_t gem_element_size() + { + return m_element_size; + } + + inline size_t get_max_element_count() + { + return m_max_element_count; + } + + inline size_t get_allocated_count() + { + return m_allocated_count; + } + + inline size_t get_free_positions_count() + { + return m_free_nodes_count; + } + + inline void * get_element_data(size_t element_index) + { + return &m_pool[element_index*m_element_size]; + } + + //! Allocates memory in pool + /*! + \param size_bytes size in bytes of the buffer + */ + void * allocate(size_t size_bytes); + + bool free(void * pointer); +}; + + + + +//! Generic Allocator with pools +/*! +General purpose Allocator which can create Memory Pools dynamiacally as needed. +*/ +class btGenericPoolAllocator +{ +protected: + size_t m_pool_element_size; + size_t m_pool_element_count; +public: + btGenericMemoryPool * m_pools[BT_DEFAULT_MAX_POOLS]; + size_t m_pool_count; + + + inline size_t get_pool_capacity() + { + return m_pool_element_size*m_pool_element_count; + } + + +protected: + // creates a pool + btGenericMemoryPool * push_new_pool(); + + void * failback_alloc(size_t size_bytes); + + bool failback_free(void * pointer); +public: + + btGenericPoolAllocator(size_t pool_element_size, size_t pool_element_count) + { + m_pool_count = 0; + m_pool_element_size = pool_element_size; + m_pool_element_count = pool_element_count; + } + + virtual ~btGenericPoolAllocator(); + + //! Allocates memory in pool + /*! + \param size_bytes size in bytes of the buffer + */ + void * allocate(size_t size_bytes); + + bool free(void * pointer); +}; + + + +/*! \defgroup POOL_MEMORY_FUNCTIONS +standar managed Memory functions. Memory pools are used. +*/ +//! @{ +void * btPoolAlloc(size_t size); +void * btPoolRealloc(void *ptr, size_t oldsize, size_t newsize); +void btPoolFree(void *ptr); +//! @} + + +#endif diff --git a/Extras/GIMPACT/src/Bullet/btGenericPoolAllocator.cpp b/Extras/GIMPACT/src/Bullet/btGenericPoolAllocator.cpp new file mode 100755 index 000000000..7a61f5679 --- /dev/null +++ b/Extras/GIMPACT/src/Bullet/btGenericPoolAllocator.cpp @@ -0,0 +1,283 @@ +/*! \file btGenericPoolAllocator.cpp +\author Francisco León Nájera. email projectileman@yahoo.com + +General purpose allocator class +*/ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "GIMPACT/Bullet/btGenericPoolAllocator.h" + + + +/// *************** btGenericMemoryPool ******************/////////// + +size_t btGenericMemoryPool::allocate_from_free_nodes(size_t num_elements) +{ + size_t ptr = BT_UINT_MAX; + + if(m_free_nodes_count == 0) return BT_UINT_MAX; + // find an avaliable free node with the correct size + size_t revindex = m_free_nodes_count; + + while(revindex-- && ptr == BT_UINT_MAX) + { + if(m_allocated_sizes[m_free_nodes[revindex]]>=num_elements) + { + ptr = revindex; + } + } + if(ptr == BT_UINT_MAX) return BT_UINT_MAX; // not found + + + revindex = ptr; + ptr = m_free_nodes[revindex]; + // post: ptr contains the node index, and revindex the index in m_free_nodes + + size_t finalsize = m_allocated_sizes[ptr]; + finalsize -= num_elements; + + m_allocated_sizes[ptr] = num_elements; + + // post: finalsize>=0, m_allocated_sizes[ptr] has the requested size + + if(finalsize>0) // preserve free node, there are some free memory + { + m_free_nodes[revindex] = ptr + num_elements; + m_allocated_sizes[ptr + num_elements] = finalsize; + } + else // delete free node + { + // swap with end + m_free_nodes[revindex] = m_free_nodes[m_free_nodes_count-1]; + m_free_nodes_count--; + } + + return ptr; +} + +size_t btGenericMemoryPool::allocate_from_pool(size_t num_elements) +{ + if(m_allocated_count+num_elements>m_max_element_count) return BT_UINT_MAX; + + size_t ptr = m_allocated_count; + + m_allocated_sizes[m_allocated_count] = num_elements; + m_allocated_count+=num_elements; + + return ptr; +} + + +void btGenericMemoryPool::init_pool(size_t element_size, size_t element_count) +{ + m_allocated_count = 0; + m_free_nodes_count = 0; + + m_element_size = element_size; + m_max_element_count = element_count; + + + + + m_pool = (unsigned char *) btAlignedAlloc(m_element_size*m_max_element_count,16); + m_free_nodes = (size_t *) btAlignedAlloc(sizeof(size_t)*m_max_element_count,16); + m_allocated_sizes = (size_t *) btAlignedAlloc(sizeof(size_t)*m_max_element_count,16); + + for (size_t i = 0;i< m_max_element_count;i++ ) + { + m_allocated_sizes[i] = 0; + } +} + +void btGenericMemoryPool::end_pool() +{ + btAlignedFree(m_pool); + btAlignedFree(m_free_nodes); + btAlignedFree(m_allocated_sizes); + m_allocated_count = 0; + m_free_nodes_count = 0; +} + + +//! Allocates memory in pool +/*! +\param size_bytes size in bytes of the buffer +*/ +void * btGenericMemoryPool::allocate(size_t size_bytes) +{ + + size_t module = size_bytes%m_element_size; + size_t element_count = size_bytes/m_element_size; + if(module>0) element_count++; + + size_t alloc_pos = allocate_from_free_nodes(element_count); + // a free node is found + if(alloc_pos != BT_UINT_MAX) + { + return get_element_data(alloc_pos); + } + // allocate directly on pool + alloc_pos = allocate_from_pool(element_count); + + if(alloc_pos == BT_UINT_MAX) return NULL; // not space + return get_element_data(alloc_pos); +} + +bool btGenericMemoryPool::free(void * pointer) +{ + unsigned char * pointer_pos = (unsigned char *)pointer; + unsigned char * pool_pos = (unsigned char *)m_pool; + // calc offset + if(pointer_pos=get_pool_capacity()) return false;// far away + + // find free position + m_free_nodes[m_free_nodes_count] = offset/m_element_size; + m_free_nodes_count++; + return true; +} + + +/// *******************! btGenericPoolAllocator *******************!/// + + +btGenericPoolAllocator::~btGenericPoolAllocator() +{ + // destroy pools + size_t i; + for (i=0;iend_pool(); + btAlignedFree(m_pools[i]); + } +} + + +// creates a pool +btGenericMemoryPool * btGenericPoolAllocator::push_new_pool() +{ + if(m_pool_count >= BT_DEFAULT_MAX_POOLS) return NULL; + + btGenericMemoryPool * newptr = (btGenericMemoryPool *)btAlignedAlloc(sizeof(btGenericMemoryPool),16); + + m_pools[m_pool_count] = newptr; + + m_pools[m_pool_count]->init_pool(m_pool_element_size,m_pool_element_count); + + m_pool_count++; + return newptr; +} + +void * btGenericPoolAllocator::failback_alloc(size_t size_bytes) +{ + + btGenericMemoryPool * pool = NULL; + + + if(size_bytes<=get_pool_capacity()) + { + pool = push_new_pool(); + } + + if(pool==NULL) // failback + { + return btAlignedAlloc(size_bytes,16); + } + + return pool->allocate(size_bytes); +} + +bool btGenericPoolAllocator::failback_free(void * pointer) +{ + btAlignedFree(pointer); + return true; +} + + +//! Allocates memory in pool +/*! +\param size_bytes size in bytes of the buffer +*/ +void * btGenericPoolAllocator::allocate(size_t size_bytes) +{ + void * ptr = NULL; + + size_t i = 0; + while(iallocate(size_bytes); + ++i; + } + + if(ptr) return ptr; + + return failback_alloc(size_bytes); +} + +bool btGenericPoolAllocator::free(void * pointer) +{ + bool result = false; + + size_t i = 0; + while(ifree(pointer); + ++i; + } + + if(result) return true; + + return failback_free(pointer); +} + +/// ************** STANDARD ALLOCATOR ***************************/// + + +#define BT_DEFAULT_POOL_SIZE 32768 +#define BT_DEFAULT_POOL_ELEMENT_SIZE 8 + +// main allocator +class BT_STANDARD_ALLOCATOR: public btGenericPoolAllocator +{ +public: + BT_STANDARD_ALLOCATOR():btGenericPoolAllocator(BT_DEFAULT_POOL_ELEMENT_SIZE,BT_DEFAULT_POOL_SIZE) + { + } +}; + +// global allocator +BT_STANDARD_ALLOCATOR g_main_allocator; + + +void * btPoolAlloc(size_t size) +{ + return g_main_allocator.allocate(size); +} + +void * btPoolRealloc(void *ptr, size_t oldsize, size_t newsize) +{ + void * newptr = btPoolAlloc(newsize); + size_t copysize = oldsize