diff --git a/dtool/metalibs/dtoolconfig/pydtool.cxx b/dtool/metalibs/dtoolconfig/pydtool.cxx index 0293df157f..3d0e149bc9 100644 --- a/dtool/metalibs/dtoolconfig/pydtool.cxx +++ b/dtool/metalibs/dtoolconfig/pydtool.cxx @@ -45,6 +45,17 @@ static PyObject *_inP07ytDId0(PyObject *self, PyObject *args); static PyObject *_inP07ytHuAm(PyObject *self, PyObject *args); static PyObject *_inP07yt_xr0(PyObject *self, PyObject *args); static PyObject *_inP07ytH5qp(PyObject *self, PyObject *args); +static PyObject *_inP07ytLfJw(PyObject *self, PyObject *args); +static PyObject *_inP07yt_Atg(PyObject *self, PyObject *args); +static PyObject *_inP07ytlBqc(PyObject *self, PyObject *args); +static PyObject *_inP07ytNdUp(PyObject *self, PyObject *args); +static PyObject *_inP07ytlS0p(PyObject *self, PyObject *args); +static PyObject *_inP07ytZZe7(PyObject *self, PyObject *args); +static PyObject *_inP07ytV5S_(PyObject *self, PyObject *args); +static PyObject *_inP07yto9vD(PyObject *self, PyObject *args); +static PyObject *_inP07ytv7tF(PyObject *self, PyObject *args); +static PyObject *_inP07ythOg6(PyObject *self, PyObject *args); +static PyObject *_inP07ytoZUn(PyObject *self, PyObject *args); static PyObject *_inP07ytq45U(PyObject *self, PyObject *args); static PyObject *_inP07yt6IPa(PyObject *self, PyObject *args); static PyObject *_inP07ytU2_B(PyObject *self, PyObject *args); @@ -74,7 +85,11 @@ static PyObject *_inP07yt3zru(PyObject *self, PyObject *args); static PyObject *_inP07ytRrg2(PyObject *self, PyObject *args); static PyObject *_inP07ytEJCx(PyObject *self, PyObject *args); static PyObject *_inP07ytWAZr(PyObject *self, PyObject *args); +static PyObject *_inP07ytHQi6(PyObject *self, PyObject *args); static PyObject *_inP07ytrD_M(PyObject *self, PyObject *args); +static PyObject *_inP07ytYaah(PyObject *self, PyObject *args); +static PyObject *_inP07yt2otr(PyObject *self, PyObject *args); +static PyObject *_inP07ytNP_b(PyObject *self, PyObject *args); static PyObject *_inP07ytjolz(PyObject *self, PyObject *args); static PyObject *_inP07ytt_JD(PyObject *self, PyObject *args); static PyObject *_inP07ytwEts(PyObject *self, PyObject *args); @@ -583,6 +598,184 @@ _inP07ytH5qp(PyObject *, PyObject *args) { return nullptr; } +/* + * Python simple wrapper for + * bool interrogate_element_has_has_function(ElementIndex element) + */ +static PyObject * +_inP07ytLfJw(PyObject *, PyObject *args) { + int param0; + if (PyArg_ParseTuple(args, "i", ¶m0)) { + bool return_value = (::interrogate_element_has_has_function)((ElementIndex)param0); + return PyBool_FromLong(return_value); + } + return nullptr; +} + +/* + * Python simple wrapper for + * FunctionIndex interrogate_element_has_function(ElementIndex element) + */ +static PyObject * +_inP07yt_Atg(PyObject *, PyObject *args) { + int param0; + if (PyArg_ParseTuple(args, "i", ¶m0)) { + FunctionIndex return_value = (::interrogate_element_has_function)((ElementIndex)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else + return PyInt_FromLong(return_value); +#endif + } + return nullptr; +} + +/* + * Python simple wrapper for + * bool interrogate_element_has_clear_function(ElementIndex element) + */ +static PyObject * +_inP07ytlBqc(PyObject *, PyObject *args) { + int param0; + if (PyArg_ParseTuple(args, "i", ¶m0)) { + bool return_value = (::interrogate_element_has_clear_function)((ElementIndex)param0); + return PyBool_FromLong(return_value); + } + return nullptr; +} + +/* + * Python simple wrapper for + * FunctionIndex interrogate_element_clear_function(ElementIndex element) + */ +static PyObject * +_inP07ytNdUp(PyObject *, PyObject *args) { + int param0; + if (PyArg_ParseTuple(args, "i", ¶m0)) { + FunctionIndex return_value = (::interrogate_element_clear_function)((ElementIndex)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else + return PyInt_FromLong(return_value); +#endif + } + return nullptr; +} + +/* + * Python simple wrapper for + * bool interrogate_element_has_del_function(ElementIndex element) + */ +static PyObject * +_inP07ytlS0p(PyObject *, PyObject *args) { + int param0; + if (PyArg_ParseTuple(args, "i", ¶m0)) { + bool return_value = (::interrogate_element_has_del_function)((ElementIndex)param0); + return PyBool_FromLong(return_value); + } + return nullptr; +} + +/* + * Python simple wrapper for + * FunctionIndex interrogate_element_del_function(ElementIndex element) + */ +static PyObject * +_inP07ytZZe7(PyObject *, PyObject *args) { + int param0; + if (PyArg_ParseTuple(args, "i", ¶m0)) { + FunctionIndex return_value = (::interrogate_element_del_function)((ElementIndex)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else + return PyInt_FromLong(return_value); +#endif + } + return nullptr; +} + +/* + * Python simple wrapper for + * bool interrogate_element_has_insert_function(ElementIndex element) + */ +static PyObject * +_inP07ytV5S_(PyObject *, PyObject *args) { + int param0; + if (PyArg_ParseTuple(args, "i", ¶m0)) { + bool return_value = (::interrogate_element_has_insert_function)((ElementIndex)param0); + return PyBool_FromLong(return_value); + } + return nullptr; +} + +/* + * Python simple wrapper for + * FunctionIndex interrogate_element_insert_function(ElementIndex element) + */ +static PyObject * +_inP07yto9vD(PyObject *, PyObject *args) { + int param0; + if (PyArg_ParseTuple(args, "i", ¶m0)) { + FunctionIndex return_value = (::interrogate_element_insert_function)((ElementIndex)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else + return PyInt_FromLong(return_value); +#endif + } + return nullptr; +} + +/* + * Python simple wrapper for + * bool interrogate_element_has_getkey_function(ElementIndex element) + */ +static PyObject * +_inP07ytv7tF(PyObject *, PyObject *args) { + int param0; + if (PyArg_ParseTuple(args, "i", ¶m0)) { + bool return_value = (::interrogate_element_has_getkey_function)((ElementIndex)param0); + return PyBool_FromLong(return_value); + } + return nullptr; +} + +/* + * Python simple wrapper for + * FunctionIndex interrogate_element_getkey_function(ElementIndex element) + */ +static PyObject * +_inP07ythOg6(PyObject *, PyObject *args) { + int param0; + if (PyArg_ParseTuple(args, "i", ¶m0)) { + FunctionIndex return_value = (::interrogate_element_getkey_function)((ElementIndex)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else + return PyInt_FromLong(return_value); +#endif + } + return nullptr; +} + +/* + * Python simple wrapper for + * FunctionIndex interrogate_element_length_function(ElementIndex element) + */ +static PyObject * +_inP07ytoZUn(PyObject *, PyObject *args) { + int param0; + if (PyArg_ParseTuple(args, "i", ¶m0)) { + FunctionIndex return_value = (::interrogate_element_length_function)((ElementIndex)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else + return PyInt_FromLong(return_value); +#endif + } + return nullptr; +} + /* * Python simple wrapper for * bool interrogate_element_is_sequence(ElementIndex element) @@ -1060,6 +1253,24 @@ _inP07ytWAZr(PyObject *, PyObject *args) { return nullptr; } +/* + * Python simple wrapper for + * FunctionIndex interrogate_wrapper_function(FunctionWrapperIndex wrapper) + */ +static PyObject * +_inP07ytHQi6(PyObject *, PyObject *args) { + int param0; + if (PyArg_ParseTuple(args, "i", ¶m0)) { + FunctionIndex return_value = (::interrogate_wrapper_function)((FunctionWrapperIndex)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else + return PyInt_FromLong(return_value); +#endif + } + return nullptr; +} + /* * Python simple wrapper for * bool interrogate_wrapper_is_callable_by_name(FunctionWrapperIndex wrapper) @@ -1074,6 +1285,48 @@ _inP07ytrD_M(PyObject *, PyObject *args) { return nullptr; } +/* + * Python simple wrapper for + * bool interrogate_wrapper_is_copy_constructor(FunctionWrapperIndex wrapper) + */ +static PyObject * +_inP07ytYaah(PyObject *, PyObject *args) { + int param0; + if (PyArg_ParseTuple(args, "i", ¶m0)) { + bool return_value = (::interrogate_wrapper_is_copy_constructor)((FunctionWrapperIndex)param0); + return PyBool_FromLong(return_value); + } + return nullptr; +} + +/* + * Python simple wrapper for + * bool interrogate_wrapper_is_coerce_constructor(FunctionWrapperIndex wrapper) + */ +static PyObject * +_inP07yt2otr(PyObject *, PyObject *args) { + int param0; + if (PyArg_ParseTuple(args, "i", ¶m0)) { + bool return_value = (::interrogate_wrapper_is_coerce_constructor)((FunctionWrapperIndex)param0); + return PyBool_FromLong(return_value); + } + return nullptr; +} + +/* + * Python simple wrapper for + * bool interrogate_wrapper_is_extension(FunctionWrapperIndex wrapper) + */ +static PyObject * +_inP07ytNP_b(PyObject *, PyObject *args) { + int param0; + if (PyArg_ParseTuple(args, "i", ¶m0)) { + bool return_value = (::interrogate_wrapper_is_extension)((FunctionWrapperIndex)param0); + return PyBool_FromLong(return_value); + } + return nullptr; +} + /* * Python simple wrapper for * bool interrogate_wrapper_has_comment(FunctionWrapperIndex wrapper) @@ -2652,6 +2905,17 @@ static PyMethodDef python_simple_funcs[] = { { "interrogate_element_getter", &_inP07ytHuAm, METH_VARARGS, nullptr }, { "interrogate_element_has_setter", &_inP07yt_xr0, METH_VARARGS, nullptr }, { "interrogate_element_setter", &_inP07ytH5qp, METH_VARARGS, nullptr }, + { "interrogate_element_has_has_function", &_inP07ytLfJw, METH_VARARGS, nullptr }, + { "interrogate_element_has_function", &_inP07yt_Atg, METH_VARARGS, nullptr }, + { "interrogate_element_has_clear_function", &_inP07ytlBqc, METH_VARARGS, nullptr }, + { "interrogate_element_clear_function", &_inP07ytNdUp, METH_VARARGS, nullptr }, + { "interrogate_element_has_del_function", &_inP07ytlS0p, METH_VARARGS, nullptr }, + { "interrogate_element_del_function", &_inP07ytZZe7, METH_VARARGS, nullptr }, + { "interrogate_element_has_insert_function", &_inP07ytV5S_, METH_VARARGS, nullptr }, + { "interrogate_element_insert_function", &_inP07yto9vD, METH_VARARGS, nullptr }, + { "interrogate_element_has_getkey_function", &_inP07ytv7tF, METH_VARARGS, nullptr }, + { "interrogate_element_getkey_function", &_inP07ythOg6, METH_VARARGS, nullptr }, + { "interrogate_element_length_function", &_inP07ytoZUn, METH_VARARGS, nullptr }, { "interrogate_element_is_sequence", &_inP07ytq45U, METH_VARARGS, nullptr }, { "interrogate_element_is_mapping", &_inP07yt6IPa, METH_VARARGS, nullptr }, { "interrogate_number_of_globals", &_inP07ytU2_B, METH_VARARGS, nullptr }, @@ -2681,7 +2945,11 @@ static PyMethodDef python_simple_funcs[] = { { "interrogate_function_number_of_python_wrappers", &_inP07ytRrg2, METH_VARARGS, nullptr }, { "interrogate_function_python_wrapper", &_inP07ytEJCx, METH_VARARGS, nullptr }, { "interrogate_wrapper_name", &_inP07ytWAZr, METH_VARARGS, nullptr }, + { "interrogate_wrapper_function", &_inP07ytHQi6, METH_VARARGS, nullptr }, { "interrogate_wrapper_is_callable_by_name", &_inP07ytrD_M, METH_VARARGS, nullptr }, + { "interrogate_wrapper_is_copy_constructor", &_inP07ytYaah, METH_VARARGS, nullptr }, + { "interrogate_wrapper_is_coerce_constructor", &_inP07yt2otr, METH_VARARGS, nullptr }, + { "interrogate_wrapper_is_extension", &_inP07ytNP_b, METH_VARARGS, nullptr }, { "interrogate_wrapper_has_comment", &_inP07ytjolz, METH_VARARGS, nullptr }, { "interrogate_wrapper_comment", &_inP07ytt_JD, METH_VARARGS, nullptr }, { "interrogate_wrapper_has_return_value", &_inP07ytwEts, METH_VARARGS, nullptr }, diff --git a/dtool/src/interrogate/functionRemap.cxx b/dtool/src/interrogate/functionRemap.cxx index 2f777f84eb..597bda5d59 100644 --- a/dtool/src/interrogate/functionRemap.cxx +++ b/dtool/src/interrogate/functionRemap.cxx @@ -312,6 +312,18 @@ make_wrapper_entry(FunctionIndex function_index) { iwrapper._flags |= InterrogateFunctionWrapper::F_callable_by_name; } + if (_flags & F_copy_constructor) { + iwrapper._flags |= InterrogateFunctionWrapper::F_copy_constructor; + } + + if (_flags & F_coerce_constructor) { + iwrapper._flags |= InterrogateFunctionWrapper::F_coerce_constructor; + } + + if (_extension) { + iwrapper._flags |= InterrogateFunctionWrapper::F_extension; + } + Parameters::const_iterator pi; for (pi = _parameters.begin(); pi != _parameters.end(); diff --git a/dtool/src/interrogate/interrogate.cxx b/dtool/src/interrogate/interrogate.cxx index 0c15cb4a3a..0c515ac662 100644 --- a/dtool/src/interrogate/interrogate.cxx +++ b/dtool/src/interrogate/interrogate.cxx @@ -417,8 +417,8 @@ main(int argc, char **argv) { break; case CO_python_native: - build_python_native = true; - break; + build_python_native = true; + break; case CO_track_interpreter: track_interpreter = true; @@ -604,23 +604,22 @@ main(int argc, char **argv) { << " *\n" << " */\n\n"; - if(the_output_include != nullptr) - { - output_code << "#include \""<get_element(element).get_setter(); } +bool +interrogate_element_has_has_function(ElementIndex element) { + // cerr << "interrogate_element_has_has_function(" << element << ")\n"; + return InterrogateDatabase::get_ptr()->get_element(element).has_has_function(); +} + +FunctionIndex +interrogate_element_has_function(ElementIndex element) { + // cerr << "interrogate_element_has_function(" << element << ")\n"; + return InterrogateDatabase::get_ptr()->get_element(element).get_has_function(); +} + +bool +interrogate_element_has_clear_function(ElementIndex element) { + // cerr << "interrogate_element_has_clear_function(" << element << ")\n"; + return InterrogateDatabase::get_ptr()->get_element(element).has_clear_function(); +} + +FunctionIndex +interrogate_element_clear_function(ElementIndex element) { + // cerr << "interrogate_element_clear_function(" << element << ")\n"; + return InterrogateDatabase::get_ptr()->get_element(element).get_clear_function(); +} + +bool +interrogate_element_has_del_function(ElementIndex element) { + // cerr << "interrogate_element_has_del_function(" << element << ")\n"; + return InterrogateDatabase::get_ptr()->get_element(element).has_del_function(); +} + +FunctionIndex +interrogate_element_del_function(ElementIndex element) { + // cerr << "interrogate_element_del_function(" << element << ")\n"; + return InterrogateDatabase::get_ptr()->get_element(element).get_del_function(); +} + +bool +interrogate_element_has_insert_function(ElementIndex element) { + // cerr << "interrogate_element_has_insert_function(" << element << ")\n"; + return InterrogateDatabase::get_ptr()->get_element(element).has_insert_function(); +} + +FunctionIndex +interrogate_element_insert_function(ElementIndex element) { + // cerr << "interrogate_element_insert_function(" << element << ")\n"; + return InterrogateDatabase::get_ptr()->get_element(element).get_insert_function(); +} + +bool +interrogate_element_has_getkey_function(ElementIndex element) { + // cerr << "interrogate_element_has_getkey_function(" << element << ")\n"; + return InterrogateDatabase::get_ptr()->get_element(element).has_getkey_function(); +} + +FunctionIndex +interrogate_element_getkey_function(ElementIndex element) { + // cerr << "interrogate_element_getkey_function(" << element << ")\n"; + return InterrogateDatabase::get_ptr()->get_element(element).get_getkey_function(); +} + +FunctionIndex +interrogate_element_length_function(ElementIndex element) { + // cerr << "interrogate_element_length_function(" << element << ")\n"; + return InterrogateDatabase::get_ptr()->get_element(element).get_length_function(); +} + bool interrogate_element_is_sequence(ElementIndex element) { // cerr << "interrogate_element_is_sequence(" << element << ")\n"; @@ -359,12 +425,36 @@ interrogate_wrapper_name(FunctionWrapperIndex wrapper) { return result.c_str(); } +FunctionIndex +interrogate_wrapper_function(FunctionWrapperIndex wrapper) { + // cerr << "interrogate_wrapper_function(" << wrapper << ")\n"; + return InterrogateDatabase::get_ptr()->get_wrapper(wrapper).get_function(); +} + bool interrogate_wrapper_is_callable_by_name(FunctionWrapperIndex wrapper) { // cerr << "interrogate_wrapper_is_callable_by_name(" << wrapper << ")\n"; return InterrogateDatabase::get_ptr()->get_wrapper(wrapper).is_callable_by_name(); } +bool +interrogate_wrapper_is_copy_constructor(FunctionWrapperIndex wrapper) { + // cerr << "interrogate_wrapper_is_copy_constructor(" << wrapper << ")\n"; + return InterrogateDatabase::get_ptr()->get_wrapper(wrapper).is_copy_constructor(); +} + +bool +interrogate_wrapper_is_coerce_constructor(FunctionWrapperIndex wrapper) { + // cerr << "interrogate_wrapper_is_coerce_constructor(" << wrapper << ")\n"; + return InterrogateDatabase::get_ptr()->get_wrapper(wrapper).is_coerce_constructor(); +} + +bool +interrogate_wrapper_is_extension(FunctionWrapperIndex wrapper) { + // cerr << "interrogate_wrapper_is_extension(" << wrapper << ")\n"; + return InterrogateDatabase::get_ptr()->get_wrapper(wrapper).is_extension(); +} + bool interrogate_wrapper_has_comment(FunctionWrapperIndex wrapper) { // cerr << "interrogate_wrapper_has_comment(" << wrapper << ")\n"; diff --git a/dtool/src/interrogatedb/interrogate_interface.h b/dtool/src/interrogatedb/interrogate_interface.h index a44f9fef92..5c776e70eb 100644 --- a/dtool/src/interrogatedb/interrogate_interface.h +++ b/dtool/src/interrogatedb/interrogate_interface.h @@ -152,6 +152,17 @@ EXPCL_INTERROGATEDB bool interrogate_element_has_getter(ElementIndex element); EXPCL_INTERROGATEDB FunctionIndex interrogate_element_getter(ElementIndex element); EXPCL_INTERROGATEDB bool interrogate_element_has_setter(ElementIndex element); EXPCL_INTERROGATEDB FunctionIndex interrogate_element_setter(ElementIndex element); +EXPCL_INTERROGATEDB bool interrogate_element_has_has_function(ElementIndex element); +EXPCL_INTERROGATEDB FunctionIndex interrogate_element_has_function(ElementIndex element); +EXPCL_INTERROGATEDB bool interrogate_element_has_clear_function(ElementIndex element); +EXPCL_INTERROGATEDB FunctionIndex interrogate_element_clear_function(ElementIndex element); +EXPCL_INTERROGATEDB bool interrogate_element_has_del_function(ElementIndex element); +EXPCL_INTERROGATEDB FunctionIndex interrogate_element_del_function(ElementIndex element); +EXPCL_INTERROGATEDB bool interrogate_element_has_insert_function(ElementIndex element); +EXPCL_INTERROGATEDB FunctionIndex interrogate_element_insert_function(ElementIndex element); +EXPCL_INTERROGATEDB bool interrogate_element_has_getkey_function(ElementIndex element); +EXPCL_INTERROGATEDB FunctionIndex interrogate_element_getkey_function(ElementIndex element); +EXPCL_INTERROGATEDB FunctionIndex interrogate_element_length_function(ElementIndex element); EXPCL_INTERROGATEDB bool interrogate_element_is_sequence(ElementIndex element); EXPCL_INTERROGATEDB bool interrogate_element_is_mapping(ElementIndex element); @@ -261,10 +272,23 @@ EXPCL_INTERROGATEDB FunctionWrapperIndex interrogate_function_python_wrapper(Fun // not identical. EXPCL_INTERROGATEDB const char *interrogate_wrapper_name(FunctionWrapperIndex wrapper); +// Returns the function that this wrapper belongs to. +EXPCL_INTERROGATEDB FunctionIndex interrogate_wrapper_function(FunctionWrapperIndex wrapper); + // This returns true if -fnames was given to interrogate, making the wrapper // function callable directly by its name. EXPCL_INTERROGATEDB bool interrogate_wrapper_is_callable_by_name(FunctionWrapperIndex wrapper); +// This returns true if this is a copy constructor. +EXPCL_INTERROGATEDB bool interrogate_wrapper_is_copy_constructor(FunctionWrapperIndex wrapper); + +// This returns true if this is a constructor that is not marked "explicit". +EXPCL_INTERROGATEDB bool interrogate_wrapper_is_coerce_constructor(FunctionWrapperIndex wrapper); + +// This returns true if this is an extension function, rather than a real +// function defined in the C++ code. +EXPCL_INTERROGATEDB bool interrogate_wrapper_is_extension(FunctionWrapperIndex wrapper); + // This returns the C++ comment written for the function wrapper, usually from // the .cpp file. There may be a different comment for each overload of a // given function. diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index ea512dd87f..fe2e0f455a 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -2373,7 +2373,7 @@ DTOOL_CONFIG=[ ("HAVE_PROC_SELF_CMDLINE", 'UNDEF', '1'), ("HAVE_PROC_CURPROC_FILE", 'UNDEF', 'UNDEF'), ("HAVE_PROC_CURPROC_MAP", 'UNDEF', 'UNDEF'), - ("HAVE_PROC_SELF_CMDLINE", 'UNDEF', 'UNDEF'), + ("HAVE_PROC_CURPROC_CMDLINE", 'UNDEF', 'UNDEF'), ("HAVE_GLOBAL_ARGV", '1', 'UNDEF'), ("PROTOTYPE_GLOBAL_ARGV", 'UNDEF', 'UNDEF'), ("GLOBAL_ARGV", '__argv', 'UNDEF'), @@ -3302,6 +3302,7 @@ if not PkgSkip("DIRECT"): CopyAllHeaders('direct/src/distributed') CopyAllHeaders('direct/src/interval') CopyAllHeaders('direct/src/showbase') + CopyAllHeaders('direct/src/motiontrail') CopyAllHeaders('direct/src/dcparse') if not PkgSkip("PANDATOOL"): diff --git a/panda/src/collide/collisionPolygon.cxx b/panda/src/collide/collisionPolygon.cxx index f44f0e2e77..51f9ffc0ea 100644 --- a/panda/src/collide/collisionPolygon.cxx +++ b/panda/src/collide/collisionPolygon.cxx @@ -787,6 +787,200 @@ test_intersection_from_segment(const CollisionEntry &entry) const { return new_entry; } +/** + * + */ +PT(CollisionEntry) CollisionPolygon:: +test_intersection_from_capsule(const CollisionEntry &entry) const { + const CollisionCapsule *capsule; + DCAST_INTO_R(capsule, entry.get_from(), nullptr); + + const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + + LPoint3 from_a = capsule->get_point_a() * wrt_mat; + LPoint3 from_b = capsule->get_point_b() * wrt_mat; + LVector3 from_radius_v = + LVector3(capsule->get_radius(), 0.0f, 0.0f) * wrt_mat; + PN_stdfloat from_radius_2 = from_radius_v.length_squared(); + PN_stdfloat from_radius = csqrt(from_radius_2); + + PN_stdfloat dist_a = get_plane().dist_to_plane(from_a); + PN_stdfloat dist_b = get_plane().dist_to_plane(from_b); + + // Some early-outs (optional) + if (dist_a >= from_radius && dist_b >= from_radius) { + // Entirely in front of the plane means no intersection. + return nullptr; + } + + if (dist_a <= -from_radius && dist_b <= -from_radius) { + // Entirely behind the plane also means no intersection. + return nullptr; + } + + LMatrix4 to_3d_mat; + rederive_to_3d_mat(to_3d_mat); + + // Find the intersection point between the capsule's axis and the plane. + LPoint3 intersect_3d; + if (!get_plane().intersects_line(intersect_3d, from_a, from_b)) { + // Completely parallel. Take an arbitrary point along the capsule axis. + intersect_3d = (from_a + from_b) * 0.5f; + } + + // Find the closest point on the polygon to this intersection point. + LPoint2 intersect_2d = to_2d(intersect_3d); + LPoint2 closest_p_2d = intersect_2d; + PN_stdfloat best_dist_2 = -1; + + size_t num_points = _points.size(); + for (size_t i = 0; i < num_points; ++i) { + const LPoint2 &p1 = _points[i]._p; + const LPoint2 &p2 = _points[(i + 1) % num_points]._p; + + // Is the intersection outside the polygon? + LVector2 v = intersect_2d - p1; + LVector2 pv = p2 - p1; + if (is_right(v, pv)) { + PN_stdfloat t = v.dot(pv) / pv.length_squared(); + t = max(min(t, (PN_stdfloat)1), (PN_stdfloat)0); + + LPoint2 p = p1 + pv * t; + PN_stdfloat d = (p - intersect_2d).length_squared(); + if (best_dist_2 < 0 || d < best_dist_2) { + closest_p_2d = p; + best_dist_2 = d; + } + } + } + + LPoint3 closest_p_3d = to_3d(closest_p_2d, to_3d_mat); + + // Now find the closest point on the capsule axis to this point. + LVector3 from_v = from_b - from_a; + + PN_stdfloat t = (closest_p_3d - from_a).dot(from_v) / from_v.length_squared(); + LPoint3 ref_point_3d = from_a + from_v * max(min(t, (PN_stdfloat)1), (PN_stdfloat)0); + + // Okay, now we have a point to apply the sphere test on. + + // The nearest point within the plane to our reference is the intersection of + // the line (reference, reference - normal) with the plane. + PN_stdfloat dist; + if (!get_plane().intersects_line(dist, ref_point_3d, -get_normal())) { + // No intersection with plane? This means the plane's effective normal + // was within the plane itself. A useless polygon. + return nullptr; + } + + if (dist > from_radius || dist < -from_radius) { + // No intersection with the plane. + return nullptr; + } + + LPoint2 ref_point_2d = to_2d(ref_point_3d); + LPoint2 surface_point_2d = ref_point_2d; + PN_stdfloat edge_dist_2 = -1; + + for (size_t i = 0; i < num_points; ++i) { + const LPoint2 &p1 = _points[i]._p; + const LPoint2 &p2 = _points[(i + 1) % num_points]._p; + + // Is the intersection outside the polygon? + LVector2 v = ref_point_2d - p1; + LVector2 pv = p2 - p1; + if (is_right(v, pv)) { + PN_stdfloat t = v.dot(pv) / pv.length_squared(); + t = max(min(t, (PN_stdfloat)1), (PN_stdfloat)0); + + LPoint2 p = p1 + pv * t; + PN_stdfloat d = (p - ref_point_2d).length_squared(); + if (edge_dist_2 < 0 || d < edge_dist_2) { + surface_point_2d = p; + edge_dist_2 = d; + } + } + } + + // Now we have edge_dist_2, which is the square of the distance from the + // reference point to the nearest edge of the polygon, within the polygon's + // plane. + + if (edge_dist_2 > from_radius_2) { + // No intersection; the circle is outside the polygon. + return nullptr; + } + + // The sphere appears to intersect the polygon. If the edge is less than + // from_radius away, the sphere may be resting on an edge of the polygon. + // Determine how far the center of the sphere must remain from the plane, + // based on its distance from the nearest edge. + + PN_stdfloat max_dist = from_radius; + if (edge_dist_2 >= 0.0f) { + PN_stdfloat max_dist_2 = max(from_radius_2 - edge_dist_2, (PN_stdfloat)0.0); + max_dist = csqrt(max_dist_2); + } + + if (dist > max_dist || -dist > max_dist) { + // There's no intersection: the sphere is hanging above or under the edge. + return nullptr; + } + + if (collide_cat.is_debug()) { + collide_cat.debug() + << "intersection detected from " << entry.get_from_node_path() + << " into " << entry.get_into_node_path() << "\n"; + } + PT(CollisionEntry) new_entry = new CollisionEntry(entry); + + LVector3 normal = (has_effective_normal() && capsule->get_respect_effective_normal()) ? get_effective_normal() : get_normal(); + new_entry->set_surface_normal(normal); + + if ((dist_a < 0 || dist_b < 0) && !IS_NEARLY_EQUAL(dist_a, dist_b)) { + // We need to report the deepest point below the polygon as the interior + // point so that the pusher will completely push it out. + LPoint3 deepest_3d = (dist_a < dist_b) ? from_a : from_b; + LPoint2 deepest_2d = to_2d(deepest_3d); + surface_point_2d = deepest_2d; + PN_stdfloat best_dist_2 = -1; + + for (size_t i = 0; i < num_points; ++i) { + const LPoint2 &p1 = _points[i]._p; + const LPoint2 &p2 = _points[(i + 1) % num_points]._p; + + // Is the deepest point outside the polygon? + LVector2 v = deepest_2d - p1; + LVector2 pv = p2 - p1; + if (is_right(v, pv)) { + PN_stdfloat t = v.dot(pv) / pv.length_squared(); + t = max(min(t, (PN_stdfloat)1), (PN_stdfloat)0); + + LPoint2 p = p1 + pv * t; + PN_stdfloat d = (p - deepest_2d).length_squared(); + if (best_dist_2 < 0 || d < best_dist_2) { + surface_point_2d = p; + best_dist_2 = d; + } + } + } + + if (best_dist_2 < 0) { + // Deepest point is completely within the polygon, easy case. + new_entry->set_surface_point(deepest_3d - normal * min(dist_a, dist_b)); + new_entry->set_interior_point(deepest_3d - normal * from_radius); + return new_entry; + } + } + + // Colliding with an edge, use the sphere test results. + LPoint3 surface_point = to_3d(surface_point_2d, to_3d_mat); + LPoint3 interior_point = ref_point_3d - normal * max_dist; + new_entry->set_surface_point(surface_point); + new_entry->set_interior_point((interior_point - surface_point).project(normal) + surface_point); + return new_entry; +} + /** * This is part of the double-dispatch implementation of test_intersection(). * It is called when the "from" object is a parabola. diff --git a/panda/src/collide/collisionPolygon.h b/panda/src/collide/collisionPolygon.h index cb62afaa2d..95ad322f7d 100644 --- a/panda/src/collide/collisionPolygon.h +++ b/panda/src/collide/collisionPolygon.h @@ -96,6 +96,8 @@ protected: virtual PT(CollisionEntry) test_intersection_from_segment(const CollisionEntry &entry) const; virtual PT(CollisionEntry) + test_intersection_from_capsule(const CollisionEntry &entry) const; + virtual PT(CollisionEntry) test_intersection_from_parabola(const CollisionEntry &entry) const; virtual PT(CollisionEntry) test_intersection_from_capsule(const CollisionEntry &entry) const; diff --git a/panda/src/egg/eggPrimitive.h b/panda/src/egg/eggPrimitive.h index 1e280a8175..f5901e25e9 100644 --- a/panda/src/egg/eggPrimitive.h +++ b/panda/src/egg/eggPrimitive.h @@ -134,10 +134,9 @@ PUBLISHED: virtual bool joint_has_primitives() const; virtual bool has_normals() const; - // The EggPrimitive itself appears to be an STL container of pointers to // EggVertex objects. The set of vertices is read-only, however, except - // through the limited add_vertexremove_vertex or inserterase interface. + // through the limited add_vertex/remove_vertex or insert/erase interface. // The following implements this. public: #ifdef _WIN32 @@ -203,8 +202,8 @@ protected: Vertices _vertices; // Don't try to use these private functions. User code should add and - // remove vertices via add_vertex()remove_vertex(), or via the STL-like - // push_back()pop_back() or insert()erase(), above. + // remove vertices via add_vertex() / remove_vertex(), or via the STL-like + // push_back() / pop_back() or insert() / erase(), above. virtual void prepare_add_vertex(EggVertex *vertex, int i, int n); virtual void prepare_remove_vertex(EggVertex *vertex, int i, int n); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index c1155efa05..aefb4c2572 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -14935,6 +14935,7 @@ do_extract_texture_data(CLP(TextureContext) *gtc) { break; case GL_LUMINANCE: #ifndef OPENGLES + case GL_LUMINANCE8_EXT: case GL_LUMINANCE16: case GL_LUMINANCE16F_ARB: #endif diff --git a/panda/src/linmath/lmatrix3_src.h b/panda/src/linmath/lmatrix3_src.h index cf5f7c6776..f46432b1d2 100644 --- a/panda/src/linmath/lmatrix3_src.h +++ b/panda/src/linmath/lmatrix3_src.h @@ -90,8 +90,8 @@ PUBLISHED: INLINE_LINMATH FLOATNAME(LVecBase3) get_col(int col) const; MAKE_SEQ(get_rows, size, get_row); MAKE_SEQ(get_cols, size, get_col); - MAKE_SEQ_PROPERTY(rows, size, get_row); - MAKE_SEQ_PROPERTY(cols, size, get_col); + MAKE_SEQ_PROPERTY(rows, size, get_row, set_row); + MAKE_SEQ_PROPERTY(cols, size, get_col, set_col); INLINE_LINMATH FLOATNAME(LVecBase2) get_row2(int row) const; INLINE_LINMATH FLOATNAME(LVecBase2) get_col2(int col) const; diff --git a/panda/src/linmath/lmatrix4_src.h b/panda/src/linmath/lmatrix4_src.h index 5400f0872b..3609f54d8d 100644 --- a/panda/src/linmath/lmatrix4_src.h +++ b/panda/src/linmath/lmatrix4_src.h @@ -105,8 +105,8 @@ PUBLISHED: MAKE_SEQ(get_rows, size, get_row); MAKE_SEQ(get_cols, size, get_col); MAKE_SEQ(get_row3s, size, get_row3); - MAKE_SEQ_PROPERTY(rows, size, get_row); - MAKE_SEQ_PROPERTY(cols, size, get_col); + MAKE_SEQ_PROPERTY(rows, size, get_row, set_row); + MAKE_SEQ_PROPERTY(cols, size, get_col, set_col); // these versions inline better INLINE_LINMATH void get_row(FLOATNAME(LVecBase4) &result_vec, int row) const;