chore(fmod): add files from Chensne/DragonNest
This commit is contained in:
commit
50fb3c6b1c
544 changed files with 315778 additions and 0 deletions
192
src/fmod_octree.h
Executable file
192
src/fmod_octree.h
Executable file
|
|
@ -0,0 +1,192 @@
|
|||
#ifndef _FMOD_OCTREE_H
|
||||
#define _FMOD_OCTREE_H
|
||||
|
||||
// This is a compramise between an octree and an axis alligned bounding box tree.
|
||||
// Basicaly an octree which splits space exactly in 8 equal quadrents each time,
|
||||
// except that only the splits that are needed to seperate the objects are actually stored.
|
||||
|
||||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_GEOMETRY
|
||||
|
||||
//#define FMOD_GEOMETRY_DEBUGGING
|
||||
//#define FMOD_23TREE
|
||||
|
||||
#include "fmod.hpp"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
|
||||
struct FMOD_AABB
|
||||
{
|
||||
float xMin;
|
||||
float xMax;
|
||||
float yMin;
|
||||
float yMax;
|
||||
float zMin;
|
||||
float zMax;
|
||||
};
|
||||
enum OctreeFlags
|
||||
{
|
||||
OCTREE_FLAG_X_SPLIT = 0x000,
|
||||
OCTREE_FLAG_Y_SPLIT = 0x001,
|
||||
OCTREE_FLAG_Z_SPLIT = 0x002,
|
||||
OCTREE_FLAG_SPLIT_MASK = 0x003,
|
||||
OCTREE_FLAG_LEAF = 0x004,
|
||||
OCTREE_FLAG_CALCULATED_AABB = 0x008,
|
||||
OCTREE_FLAG_EXTRA_NODE = 0x010,
|
||||
OCTREE_FLAG_FREE = 0x020,
|
||||
OCTREE_FLAG_INSERTED = 0x040,
|
||||
OCTREE_FLAG_23LEAF = 0x080,
|
||||
OCTREE_FLAG_23ROOT = 0x100,
|
||||
OCTREE_FLAG_23NODE = 0x200,
|
||||
OCTREE_FLAG_INTERNAL_NODE = 0x400,
|
||||
};
|
||||
|
||||
struct OctreeNode
|
||||
{
|
||||
FMOD_AABB aabb;
|
||||
int flags;
|
||||
unsigned int splitLevel;
|
||||
unsigned int pos[3];
|
||||
|
||||
OctreeNode *parent;
|
||||
OctreeNode *hi;
|
||||
OctreeNode *lo;
|
||||
OctreeNode *nextItem;
|
||||
};
|
||||
|
||||
class Octree
|
||||
{
|
||||
public:
|
||||
// data stucture for the recursive testLine to save on extra
|
||||
// parameters on the stack.
|
||||
struct RecursionData
|
||||
{
|
||||
bool (*octreeLineTestCallback)(OctreeNode* item, void* data);
|
||||
void *data;
|
||||
bool exit;
|
||||
};
|
||||
|
||||
// see setMaxSize for description of maxSize
|
||||
Octree(float maxSize);
|
||||
~Octree();
|
||||
|
||||
OctreeNode* mRoot;
|
||||
FMOD_VECTOR mCenter;
|
||||
float mScale;
|
||||
OctreeNode* mFreeList;
|
||||
|
||||
// Inserting / deleting and updating items
|
||||
void insertItem(OctreeNode* item);
|
||||
void deleteItem(OctreeNode* item);
|
||||
void updateItem(OctreeNode* item);
|
||||
|
||||
// For update optimzation
|
||||
bool needsReinsert(OctreeNode* item);
|
||||
void updateItemAABB(OctreeNode* item) { adjustAABBs(item); }
|
||||
|
||||
// Get the Axis Aligned Bounding Box that bounds the entire tree
|
||||
void getAABB(FMOD_AABB* aabb);
|
||||
|
||||
// Internal nodes.
|
||||
// A memory pool for internal tree nodes.
|
||||
// The user is responsible for providing enough internal nodes.
|
||||
// The maximum number of internal nodes necessery is equal to the number of
|
||||
// leaf nodes added with insertItem.
|
||||
void addInternalNode(OctreeNode* item);
|
||||
void removeInternalNode(OctreeNode* item);
|
||||
|
||||
// Debugging functions
|
||||
#if defined(_DEBUG) && defined(FMOD_GEOMETRY_DEBUGGING)
|
||||
void checkTree(OctreeNode* node);
|
||||
void calculateAverageNodeElements();
|
||||
void checkNodeIsContained(OctreeNode* node);
|
||||
void calculateAverageNodeElements(OctreeNode* node);
|
||||
#endif
|
||||
|
||||
// same maxSize as passed as a parameter to the constructor.
|
||||
// sets the maximum range in x,y and z for the tree.
|
||||
// If the range is too large the tree will loose precision and
|
||||
// if the range is too small, dimensions may wrap and items
|
||||
// may end up in the top node. In both cases, the tree
|
||||
// will still return all desired intersecting nodes, but may
|
||||
// be very slow.
|
||||
void setMaxSize(float maxSize);
|
||||
|
||||
// test a line for collision with the tree
|
||||
bool testLine(bool (*octreeLineTestCallback)(OctreeNode* item, void* data), void* data, const FMOD_VECTOR& a, const FMOD_VECTOR& b);
|
||||
|
||||
#if defined(FMOD_GEOMETRY_DEBUGGING)
|
||||
void renderTree(void (*renderBox)(float xMin, float xMax, float yMin, float yMax, float zMin, float zMax));
|
||||
void renderTreeInternal(OctreeNode* node, void (*renderBox)(float xMin, float xMax, float yMin, float yMax, float zMin, float zMax));
|
||||
#endif
|
||||
|
||||
#if defined(FMOD_23TREE)
|
||||
// Use a 2-3-tree for to keep a sorted list of elements in each node.
|
||||
// This could be used to speed up the pathalogical case where there
|
||||
// are many AABBs in the one node. However, it may be slower in the
|
||||
// average case.
|
||||
// remove23Tree not implemented yet.
|
||||
void insert23Tree(OctreeNode* parent, OctreeNode** pParent, OctreeNode* item);
|
||||
void split23Tree(OctreeNode* node, OctreeNode* item);
|
||||
void remove23Tree(OctreeNode* item);
|
||||
void check23Tree(OctreeNode* parent, OctreeNode** pParent);
|
||||
void check23TreeRecursive(OctreeNode* node);
|
||||
int unsigned findLowest(OctreeNode* node);
|
||||
#endif
|
||||
|
||||
|
||||
static unsigned int ftoint(float f)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
#if (defined(PLATFORM_WINDOWS) && !defined(__MINGW32__) || defined(PLATFORM_XBOX)) && defined(PLATFORM_32BIT)
|
||||
|
||||
__asm fld f;
|
||||
__asm fistp i;
|
||||
|
||||
#else
|
||||
|
||||
i = (int)f;
|
||||
|
||||
#endif
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
// transformation functions
|
||||
unsigned int xGetCenter(OctreeNode* node)
|
||||
{
|
||||
return ftoint((((node->aabb.xMin + node->aabb.xMax) * 0.5f - mCenter.x) * mScale * (float)(1 << 30)) + (float)(1 << 30));
|
||||
}
|
||||
unsigned int yGetCenter(OctreeNode* node)
|
||||
{
|
||||
return ftoint((((node->aabb.yMin + node->aabb.yMax) * 0.5f - mCenter.y) * mScale * (float)(1 << 30)) + (float)(1 << 30));
|
||||
}
|
||||
unsigned int zGetCenter(OctreeNode* node)
|
||||
{
|
||||
return ftoint((((node->aabb.zMin + node->aabb.zMax) * 0.5f - mCenter.z) * mScale * (float)(1 << 30)) + (float)(1 << 30));
|
||||
}
|
||||
|
||||
private:
|
||||
void insertInternal(OctreeNode* node, OctreeNode* item);
|
||||
void addToFreeList(OctreeNode* item);
|
||||
OctreeNode* getFreeNode();
|
||||
void adjustAABBs(OctreeNode* node);
|
||||
|
||||
// each node of the tree potentially has a list of leaf nodes that are too close to be split.
|
||||
// these functions make adding and removing for this list easier.
|
||||
void removeListItem(OctreeNode* next);
|
||||
void addListItem(OctreeNode* list, OctreeNode* node);
|
||||
|
||||
static void testLine(OctreeNode* node, FMOD_VECTOR a, FMOD_VECTOR b, RecursionData* recursionData);
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // FMOD_SUPPORT_GEOMETRY
|
||||
|
||||
#endif // _FMOD_OCTREE_H
|
||||
Loading…
Add table
Add a link
Reference in a new issue