所以我已经到了需要开始将GLM的许多功能包装到我的嵌入式Python模块中的地步。
GLM的一个优点是它定义了所有典型的向量数学函数(length
、normalize
等)作为独立的静态函数。这在编写C++时效果很好,但是当尝试将此功能包装为类定义的一部分时,它会在事情上投入扳手。
我想在我的Vec3F
类上调用len
,并让它调用正确的length
重载,同时将self
作为第一个也是唯一的参数传递。Boost.Python文档相当不透明,没有很多例子,所以我甚至不知道这是否可能。
在vec2
和vec3
结构中实现length
函数是不可能的,因为这些结构在另一个项目中;我必须按原样处理结构。
任何帮助将不胜感激!
蟒蛇接口
Vec3F v
v.x = 1.0
v.y = 1.0
v.z = 1.0
print len(v) # should print 1.732050...
模块定义
template<typename T>
struct vec2
{
T x;
T y;
};
template<typename T>
struct vec3
{
T x;
T y;
T z;
};
template<typename T>
float length(vec2& v)
{
return sqrt(v.x * v.x + v.y * v.y);
}
template<typename T>
float length(vec3& v)
{
return sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
}
BOOST_PYTHON_MODULE(naga)
{
class_<vec2<float>, "Vec2F")
.def("x", &vec2<float>::x)
.def("y", &vec2<float>::y)
.def("__len__", /* ??? */); // not sure what needs to be here!
class_<vec3<float>, "Vec3F")
.def("x", &vec2<float>::x)
.def("y", &vec2<float>::y)
.def("__len__", /* ??? */); // not sure what needs to be here!
}
需要一个包装类,但仍然__len__
不会返回正确的结果,可能是因为返回值在内部转换为整数(我怀疑__len__
必须始终返回整数值)。因此,您需要将其公开为len
以获得正确的浮点返回值。
namespace bp = boost::python;
template<typename T>
struct vec2
{
T x;
T y;
};
template<typename T>
struct vec3
{
T x;
T y;
T z;
};
template <typename T>
struct vec2_wrapper : vec2<T>
{
float length()
{
return sqrt(x * x + y * y);
}
};
template <typename T>
struct vec3_wrapper : vec3<T>
{
float length()
{
return sqrt(x * x + y * y + z * z);
}
};
BOOST_PYTHON_MODULE(naga)
{
bp::class_ < vec2_wrapper<float> >("Vec2F")
.def_readwrite("x", &vec2_wrapper<float>::x)
.def_readwrite("y", &vec2_wrapper<float>::y)
.def("__len__", &vec2_wrapper<float>::length)
.def("len", &vec2_wrapper<float>::length)
;
bp::class_ < vec3_wrapper<float> >("Vec3F")
.def_readwrite("x", &vec3_wrapper<float>::x)
.def_readwrite("y", &vec3_wrapper<float>::y)
.def_readwrite("z", &vec3_wrapper<float>::z)
.def("__len__", &vec3_wrapper<float>::length)
.def("len", &vec3_wrapper<float>::length)
;
}
蟒蛇测试:
import naga as vec
v = vec.Vec3F()
v.x = 1.0
v.y = 1.0
v.z = 1.0
print "len(v):", len(v)
print "v.len():", v.len()
输出:
len(v): 1
v.len(): 1.73205077648