mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
collide: Expose CollisionPolygon's setup_points and verify_points to Python
Closes #1035
This commit is contained in:
parent
3d5f0b7fe1
commit
ac6a1a7874
@ -3829,6 +3829,7 @@ OPTS=['DIR:panda/src/collide']
|
|||||||
IGATEFILES=GetDirectoryContents('panda/src/collide', ["*.h", "*_composite*.cxx"])
|
IGATEFILES=GetDirectoryContents('panda/src/collide', ["*.h", "*_composite*.cxx"])
|
||||||
TargetAdd('libp3collide.in', opts=OPTS, input=IGATEFILES)
|
TargetAdd('libp3collide.in', opts=OPTS, input=IGATEFILES)
|
||||||
TargetAdd('libp3collide.in', opts=['IMOD:panda3d.core', 'ILIB:libp3collide', 'SRCDIR:panda/src/collide'])
|
TargetAdd('libp3collide.in', opts=['IMOD:panda3d.core', 'ILIB:libp3collide', 'SRCDIR:panda/src/collide'])
|
||||||
|
PyTargetAdd('p3collide_ext_composite.obj', opts=OPTS, input='p3collide_ext_composite.cxx')
|
||||||
|
|
||||||
#
|
#
|
||||||
# DIRECTORY: panda/src/parametrics/
|
# DIRECTORY: panda/src/parametrics/
|
||||||
@ -4073,6 +4074,7 @@ PyTargetAdd('core.pyd', input='p3event_pythonTask.obj')
|
|||||||
PyTargetAdd('core.pyd', input='p3gobj_ext_composite.obj')
|
PyTargetAdd('core.pyd', input='p3gobj_ext_composite.obj')
|
||||||
PyTargetAdd('core.pyd', input='p3pgraph_ext_composite.obj')
|
PyTargetAdd('core.pyd', input='p3pgraph_ext_composite.obj')
|
||||||
PyTargetAdd('core.pyd', input='p3display_ext_composite.obj')
|
PyTargetAdd('core.pyd', input='p3display_ext_composite.obj')
|
||||||
|
PyTargetAdd('core.pyd', input='p3collide_ext_composite.obj')
|
||||||
|
|
||||||
PyTargetAdd('core.pyd', input='core_module.obj')
|
PyTargetAdd('core.pyd', input='core_module.obj')
|
||||||
if not GetLinkAllStatic() and GetTarget() != 'emscripten':
|
if not GetLinkAllStatic() and GetTarget() != 'emscripten':
|
||||||
|
@ -65,11 +65,16 @@ set(P3COLLIDE_SOURCES
|
|||||||
config_collide.cxx
|
config_collide.cxx
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set(P3COLLIDE_IGATEEXT
|
||||||
|
collisionPolygon_ext.cxx
|
||||||
|
collisionPolygon_ext.h
|
||||||
|
)
|
||||||
|
|
||||||
composite_sources(p3collide P3COLLIDE_SOURCES)
|
composite_sources(p3collide P3COLLIDE_SOURCES)
|
||||||
add_component_library(p3collide SYMBOL BUILDING_PANDA_COLLIDE
|
add_component_library(p3collide SYMBOL BUILDING_PANDA_COLLIDE
|
||||||
${P3COLLIDE_HEADERS} ${P3COLLIDE_SOURCES})
|
${P3COLLIDE_HEADERS} ${P3COLLIDE_SOURCES})
|
||||||
target_link_libraries(p3collide p3tform)
|
target_link_libraries(p3collide p3tform)
|
||||||
target_interrogate(p3collide ALL)
|
target_interrogate(p3collide ALL EXTENSIONS ${P3COLLIDE_IGATEEXT})
|
||||||
|
|
||||||
if(NOT BUILD_METALIBS)
|
if(NOT BUILD_METALIBS)
|
||||||
install(TARGETS p3collide
|
install(TARGETS p3collide
|
||||||
|
@ -59,6 +59,9 @@ PUBLISHED:
|
|||||||
bool is_valid() const;
|
bool is_valid() const;
|
||||||
bool is_concave() const;
|
bool is_concave() const;
|
||||||
|
|
||||||
|
EXTENSION(static bool verify_points(PyObject *points));
|
||||||
|
EXTENSION(void setup_points(PyObject *points));
|
||||||
|
|
||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
MAKE_SEQ_PROPERTY(points, get_num_points, get_point);
|
MAKE_SEQ_PROPERTY(points, get_num_points, get_point);
|
||||||
MAKE_PROPERTY(valid, is_valid);
|
MAKE_PROPERTY(valid, is_valid);
|
||||||
@ -71,6 +74,8 @@ public:
|
|||||||
const CullTraverserData &data,
|
const CullTraverserData &data,
|
||||||
bool bounds_only) const;
|
bool bounds_only) const;
|
||||||
|
|
||||||
|
void setup_points(const LPoint3 *begin, const LPoint3 *end);
|
||||||
|
|
||||||
virtual PStatCollector &get_volume_pcollector();
|
virtual PStatCollector &get_volume_pcollector();
|
||||||
virtual PStatCollector &get_test_pcollector();
|
virtual PStatCollector &get_test_pcollector();
|
||||||
|
|
||||||
@ -128,7 +133,6 @@ private:
|
|||||||
PN_stdfloat dist_to_polygon(const LPoint2 &p, LPoint2 &edge_p, const Points &points) const;
|
PN_stdfloat dist_to_polygon(const LPoint2 &p, LPoint2 &edge_p, const Points &points) const;
|
||||||
void project(const LVector3 &axis, PN_stdfloat ¢er, PN_stdfloat &extent) const;
|
void project(const LVector3 &axis, PN_stdfloat ¢er, PN_stdfloat &extent) const;
|
||||||
|
|
||||||
void setup_points(const LPoint3 *begin, const LPoint3 *end);
|
|
||||||
INLINE LPoint2 to_2d(const LVecBase3 &point3d) const;
|
INLINE LPoint2 to_2d(const LVecBase3 &point3d) const;
|
||||||
INLINE void calc_to_3d_mat(LMatrix4 &to_3d_mat) const;
|
INLINE void calc_to_3d_mat(LMatrix4 &to_3d_mat) const;
|
||||||
INLINE void rederive_to_3d_mat(LMatrix4 &to_3d_mat) const;
|
INLINE void rederive_to_3d_mat(LMatrix4 &to_3d_mat) const;
|
||||||
|
86
panda/src/collide/collisionPolygon_ext.cxx
Normal file
86
panda/src/collide/collisionPolygon_ext.cxx
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/**
|
||||||
|
* PANDA 3D SOFTWARE
|
||||||
|
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||||
|
*
|
||||||
|
* All use of this software is subject to the terms of the revised BSD
|
||||||
|
* license. You should have received a copy of this license along
|
||||||
|
* with this source code in a file named "LICENSE."
|
||||||
|
*
|
||||||
|
* @file collisionPolygon_ext.cxx
|
||||||
|
* @author Derzsi Daniel
|
||||||
|
* @date 2020-10-13
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "collisionPolygon_ext.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_PYTHON
|
||||||
|
|
||||||
|
#include "collisionPolygon.h"
|
||||||
|
|
||||||
|
#ifdef STDFLOAT_DOUBLE
|
||||||
|
extern struct Dtool_PyTypedObject Dtool_LPoint3d;
|
||||||
|
#else
|
||||||
|
extern struct Dtool_PyTypedObject Dtool_LPoint3f;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies that the indicated Python list of points will define a
|
||||||
|
* CollisionPolygon.
|
||||||
|
*/
|
||||||
|
bool Extension<CollisionPolygon>::
|
||||||
|
verify_points(PyObject *points) {
|
||||||
|
const pvector<LPoint3> vec = convert_points(points);
|
||||||
|
const LPoint3 *verts_begin = &vec[0];
|
||||||
|
const LPoint3 *verts_end = verts_begin + vec.size();
|
||||||
|
|
||||||
|
return CollisionPolygon::verify_points(verts_begin, verts_end);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes this CollisionPolygon with the given Python list of
|
||||||
|
* points.
|
||||||
|
*/
|
||||||
|
void Extension<CollisionPolygon>::
|
||||||
|
setup_points(PyObject *points) {
|
||||||
|
const pvector<LPoint3> vec = convert_points(points);
|
||||||
|
const LPoint3 *verts_begin = &vec[0];
|
||||||
|
const LPoint3 *verts_end = verts_begin + vec.size();
|
||||||
|
|
||||||
|
_this->setup_points(verts_begin, verts_end);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a Python sequence to a list of LPoint3 objects.
|
||||||
|
*/
|
||||||
|
pvector<LPoint3> Extension<CollisionPolygon>::
|
||||||
|
convert_points(PyObject *points) {
|
||||||
|
pvector<LPoint3> vec;
|
||||||
|
PyObject *seq = PySequence_Fast(points, "function expects a sequence");
|
||||||
|
|
||||||
|
if (!seq) {
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject **items = PySequence_Fast_ITEMS(seq);
|
||||||
|
Py_ssize_t len = PySequence_Fast_GET_SIZE(seq);
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
vec.reserve(len);
|
||||||
|
|
||||||
|
for (Py_ssize_t i = 0; i < len; ++i) {
|
||||||
|
#ifdef STDFLOAT_DOUBLE
|
||||||
|
if (ptr = DtoolInstance_UPCAST(items[i], Dtool_LPoint3d)) {
|
||||||
|
#else
|
||||||
|
if (ptr = DtoolInstance_UPCAST(items[i], Dtool_LPoint3f)) {
|
||||||
|
#endif
|
||||||
|
vec.push_back(*(LPoint3 *)ptr);
|
||||||
|
} else {
|
||||||
|
collide_cat.warning() << "Argument must be of LPoint3 type.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_DECREF(seq);
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
43
panda/src/collide/collisionPolygon_ext.h
Normal file
43
panda/src/collide/collisionPolygon_ext.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/**
|
||||||
|
* PANDA 3D SOFTWARE
|
||||||
|
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||||
|
*
|
||||||
|
* All use of this software is subject to the terms of the revised BSD
|
||||||
|
* license. You should have received a copy of this license along
|
||||||
|
* with this source code in a file named "LICENSE."
|
||||||
|
*
|
||||||
|
* @file collisionPolygon_ext.h
|
||||||
|
* @author Derzsi Daniel
|
||||||
|
* @date 2020-10-13
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef COLLISIONPOLYGON_EXT_H
|
||||||
|
#define COLLISIONPOLYGON_EXT_H
|
||||||
|
|
||||||
|
#include "pandabase.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_PYTHON
|
||||||
|
|
||||||
|
#include "extension.h"
|
||||||
|
#include "collisionPolygon.h"
|
||||||
|
#include "py_panda.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class defines the extension methods for CollisionPolygon, which are called
|
||||||
|
* instead of any C++ methods with the same prototype.
|
||||||
|
*
|
||||||
|
* @since 1.11.0
|
||||||
|
*/
|
||||||
|
template<>
|
||||||
|
class Extension<CollisionPolygon> : public ExtensionBase<CollisionPolygon> {
|
||||||
|
public:
|
||||||
|
static bool verify_points(PyObject *points);
|
||||||
|
void setup_points(PyObject *points);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static pvector<LPoint3> convert_points(PyObject *points);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HAVE_PYTHON
|
||||||
|
|
||||||
|
#endif
|
1
panda/src/collide/p3collide_ext_composite.cxx
Normal file
1
panda/src/collide/p3collide_ext_composite.cxx
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "collisionPolygon_ext.cxx"
|
45
tests/collide/test_collision_polygon.py
Normal file
45
tests/collide/test_collision_polygon.py
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
from panda3d import core
|
||||||
|
|
||||||
|
|
||||||
|
def test_collision_polygon_verify_not_enough_points():
|
||||||
|
# Less than 3 points cannot create a polygon
|
||||||
|
assert not core.CollisionPolygon.verify_points([])
|
||||||
|
assert not core.CollisionPolygon.verify_points([core.LPoint3(1, 0, 0)])
|
||||||
|
assert not core.CollisionPolygon.verify_points([core.LPoint3(1, 0, 0), core.LPoint3(0, 0, 1)])
|
||||||
|
|
||||||
|
|
||||||
|
def test_collision_polygon_verify_repeating_points():
|
||||||
|
# Repeating points cannot create a polygon
|
||||||
|
assert not core.CollisionPolygon.verify_points([core.LPoint3(1, 0, 0), core.LPoint3(1, 0, 0), core.LPoint3(0, 0, 1)])
|
||||||
|
assert not core.CollisionPolygon.verify_points([core.LPoint3(3, 6, 1), core.LPoint3(1, 3, 5), core.LPoint3(9, 1, 2), core.LPoint3(1, 3, 5)])
|
||||||
|
|
||||||
|
|
||||||
|
def test_collision_polygon_verify_colinear_points():
|
||||||
|
# Colinear points cannot create a polygon
|
||||||
|
assert not core.CollisionPolygon.verify_points([core.LPoint3(1, 2, 3), core.LPoint3(2, 3, 4), core.LPoint3(3, 4, 5)])
|
||||||
|
assert not core.CollisionPolygon.verify_points([core.LPoint3(2, 1, 1), core.LPoint3(3, 2, 1), core.LPoint3(4, 3, 1)])
|
||||||
|
|
||||||
|
|
||||||
|
def test_collision_polygon_verify_points():
|
||||||
|
# Those should be regular, colinear points
|
||||||
|
assert core.CollisionPolygon.verify_points([core.LPoint3(1, 0, 0), core.LPoint3(0, 1, 0), core.LPoint3(0, 0, 1)])
|
||||||
|
assert core.CollisionPolygon.verify_points([core.LPoint3(10, 2, 8), core.LPoint3(7, 1, 3), core.LPoint3(5, 9, 6)])
|
||||||
|
assert core.CollisionPolygon.verify_points([core.LPoint3(3, -8, -7), core.LPoint3(9, 10, 8), core.LPoint3(7, 0, 10), core.LPoint3(-6, -2, 3)])
|
||||||
|
assert core.CollisionPolygon.verify_points([core.LPoint3(-1, -3, -5), core.LPoint3(10, 3, -10), core.LPoint3(-10, 10, -4), core.LPoint3(0, 1, -4), core.LPoint3(-9, -2, 0)])
|
||||||
|
|
||||||
|
|
||||||
|
def test_collision_polygon_setup_points():
|
||||||
|
# Create empty collision polygon
|
||||||
|
polygon = core.CollisionPolygon(core.LVecBase3(0, 0, 0), core.LVecBase3(0, 0, 0), core.LVecBase3(0, 0, 0))
|
||||||
|
assert not polygon.is_valid()
|
||||||
|
|
||||||
|
# Test our setup method against a few test cases
|
||||||
|
for points in [
|
||||||
|
[core.LPoint3(-1, -3, -5), core.LPoint3(10, 3, -10), core.LPoint3(-10, 10, -4), core.LPoint3(0, 1, -4), core.LPoint3(-9, -2, 0)],
|
||||||
|
[core.LPoint3(3, -8, -7), core.LPoint3(9, 10, 8), core.LPoint3(7, 0, 10), core.LPoint3(-6, -2, 3)],
|
||||||
|
[core.LPoint3(1, 0, 0), core.LPoint3(0, 1, 0), core.LPoint3(0, 0, 1)],
|
||||||
|
[core.LPoint3(10, 2, 8), core.LPoint3(7, 1, 3), core.LPoint3(5, 9, 6)]
|
||||||
|
]:
|
||||||
|
polygon.setup_points(points)
|
||||||
|
assert polygon.is_valid()
|
||||||
|
assert polygon.get_num_points() == len(points)
|
Loading…
x
Reference in New Issue
Block a user