Skip to content

Commit

Permalink
UPBGE: Implement BVH generation from KX_Mesh. (#736)
Browse files Browse the repository at this point in the history
The python function KX_Mesh.constructBvh now returns a new BVH Tree
based on the mesh geometry where every indices elements of the tree
correspond to the polygons indices.
  • Loading branch information
panzergame authored Jul 30, 2018
1 parent f72f4c0 commit 59d33db
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 1 deletion.
7 changes: 7 additions & 0 deletions doc/python_api/rst/bge_types/bge.types.KX_Mesh.rst
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,10 @@ base class --- :class:`EXP_Value`

:return: a duplicated mesh of the current used.
:rtype: :class:`KX_Mesh`.

.. method:: constructBvh()

Return a BVH tree based on mesh geometry. Indices of tree elements match polygons indices.

:return: A BVH tree based on mesh geometry.
:rtype: :class:`mathutils.bvhtree.BVHTree`
2 changes: 1 addition & 1 deletion source/blender/python/mathutils/mathutils_bvhtree.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ typedef struct {
/** \name Utility helper functions
* \{ */

static PyObject *bvhtree_CreatePyObject(
PyObject *bvhtree_CreatePyObject(
BVHTree *tree, float epsilon,

float (*coords)[3], unsigned int coords_len,
Expand Down
11 changes: 11 additions & 0 deletions source/blender/python/mathutils/mathutils_bvhtree.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,22 @@
#ifndef __MATHUTILS_BVHTREE_H__
#define __MATHUTILS_BVHTREE_H__

typedef struct BVHTree BVHTree;

PyMODINIT_FUNC PyInit_mathutils_bvhtree(void);

extern PyTypeObject PyBVHTree_Type;

#define PyBVHTree_Check(v) PyObject_TypeCheck((v), &PyBVHTree_Type)
#define PyBVHTree_CheckExact(v) (Py_TYPE(v) == &PyBVHTree_Type)

PyObject *bvhtree_CreatePyObject(
BVHTree *tree, float epsilon,

float (*coords)[3], unsigned int coords_len,
unsigned int (*tris)[3], unsigned int tris_len,

/* optional arrays */
int *orig_index, float (*orig_normal)[3]);

#endif /* __MATHUTILS_BVHTREE_H__ */
73 changes: 73 additions & 0 deletions source/gameengine/Ketsji/KX_Mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@
#include "EXP_PyObjectPlus.h"
#include "EXP_ListWrapper.h"

#include "BLI_kdopbvh.h"

#include "MEM_guardedalloc.h"

extern "C" {
# include "mathutils_bvhtree.h"
}

KX_Mesh::KX_Mesh(KX_Scene *scene, Mesh *mesh, const RAS_Mesh::LayersInfo& layersInfo)
:RAS_Mesh(mesh, layersInfo),
m_scene(scene)
Expand Down Expand Up @@ -108,6 +116,7 @@ PyMethodDef KX_Mesh::Methods[] = {
{"transformUV", (PyCFunction)KX_Mesh::sPyTransformUV, METH_VARARGS},
{"replaceMaterial", (PyCFunction)KX_Mesh::sPyReplaceMaterial, METH_VARARGS},
{"copy", (PyCFunction)KX_Mesh::sPyCopy, METH_NOARGS},
{"constructBvh", (PyCFunction)KX_Mesh::sPyConstructBvh, METH_VARARGS},
{nullptr, nullptr} //Sentinel
};

Expand Down Expand Up @@ -392,6 +401,70 @@ PyObject *KX_Mesh::PyCopy()
return dupli->GetProxy();
}

PyObject *KX_Mesh::PyConstructBvh(PyObject *args, PyObject *kwds)
{
float epsilon = 0.0f;

if (!PyArg_ParseTuple(args, "|f:constructBvh", &epsilon)) {
return nullptr;
}

BVHTree *tree = BLI_bvhtree_new(m_numPolygons, epsilon, 4, 6);

unsigned int numVert = 0;
// Compute the totale number of vertices.
for (const PolygonRangeInfo& range : m_polygonRanges) {
numVert += range.array->GetVertexCount();
}

float (*coords)[3] = (float (*)[3])MEM_mallocN(sizeof(float[3]) * numVert, __func__);

This comment has been minimized.

Copy link
@joelgomes1994

joelgomes1994 Jul 30, 2018

@panzergame
Raising a syntax error on Visual Studio 2015.
image

This comment has been minimized.

Copy link
@panzergame

panzergame Jul 30, 2018

Author Contributor

Do you have other error message around the one you provided ? Else if you replace __func__ by "" ?
It's definitively compiling on linux…

This comment has been minimized.

Copy link
@lordloki

lordloki Jul 30, 2018

Member

And it compiled in msvc 2017...
I will do a clean compile this night

This comment has been minimized.

Copy link
@joelgomes1994

joelgomes1994 Jul 31, 2018

@panzergame No other error messages on console, however, replacing __func__ by "" fixes the error and it builds correctly. Please, add this fix to master. Thanks. 😄

This comment has been minimized.

Copy link
@panzergame

panzergame Jul 31, 2018

Author Contributor

@joelgomes1994 What is your OS and compiler version ? This macro is used in the blender code too.

This comment has been minimized.

Copy link
@lordloki

lordloki Jul 31, 2018

Member

@panzergame there is to use BLI_compiler_compat.h

This comment has been minimized.

Copy link
@panzergame

panzergame Jul 31, 2018

Author Contributor

Ok… ce3a765, this is a part of ISO C99…

This comment has been minimized.

Copy link
@joelgomes1994

joelgomes1994 Aug 1, 2018

@panzergame
Windows 7 Ultimate x64
Microsoft Visual Studio 14.0 (Visual Studio 2015)
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x86

// Convert the vertices.
{
unsigned vertBase = 0;
for (const PolygonRangeInfo& range : m_polygonRanges) {
RAS_DisplayArray *array = range.array;
for (unsigned int i = 0, size = array->GetVertexCount(); i < size; ++i) {
copy_v3_v3(coords[vertBase + i], array->GetPosition(i).data);
}
vertBase += array->GetVertexCount();
}
}

unsigned int *tris = (unsigned int *)MEM_mallocN(sizeof(unsigned int) * 3 * m_numPolygons, __func__);
// Convert the indices.
{
unsigned int index = 0;
unsigned int vertBase = 0;
for (const PolygonRangeInfo& range : m_polygonRanges) {
// Iterate by triangle (3 indices).
for (; index < range.endIndex; index += 3) {
// Get the relative triangle base index.
const unsigned int triBase = index - range.startIndex;
float co[3][3];

for (unsigned short i = 0; i < 3; ++i) {
// Get the absolute the vertex index.
const unsigned int vertIndex = vertBase + range.array->GetTriangleIndex(triBase + i);

tris[index + i] = vertIndex;
copy_v3_v3(co[i], coords[vertIndex]);
}

BLI_bvhtree_insert(tree, index / 3, co[0], 3);
}
vertBase += range.array->GetVertexCount();
}
}

BLI_bvhtree_balance(tree);

return bvhtree_CreatePyObject(
tree, epsilon,
coords, numVert,
(unsigned int (*)[3])tris, m_numPolygons * 3,
nullptr, nullptr);
}

PyObject *KX_Mesh::pyattr_get_materials(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef)
{
KX_Mesh *self = static_cast<KX_Mesh *>(self_v);
Expand Down
1 change: 1 addition & 0 deletions source/gameengine/Ketsji/KX_Mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class KX_Mesh : public EXP_Value, public RAS_Mesh
EXP_PYMETHOD(KX_Mesh, TransformUV);
EXP_PYMETHOD(KX_Mesh, ReplaceMaterial);
EXP_PYMETHOD_NOARGS(KX_Mesh, Copy);
EXP_PYMETHOD(KX_Mesh, ConstructBvh);

static PyObject *pyattr_get_materials(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef);
static PyObject *pyattr_get_numMaterials(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef);
Expand Down

0 comments on commit 59d33db

Please sign in to comment.