Skip to content

Commit

Permalink
Migrate MathInterface to pybind11
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Jul 20, 2017
1 parent 7563a3b commit 22d6b35
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 90 deletions.
159 changes: 77 additions & 82 deletions plugins/script/interfaces/MathInterface.cpp
@@ -1,5 +1,8 @@
#include "MathInterface.h"

#include <pybind11/pybind11.h>
#include <pybind11/operators.h>

#include "math/FloatTools.h"
#include "math/AABB.h"
#include "math/Vector2.h"
Expand All @@ -10,100 +13,92 @@
namespace script {

// IScriptInterface implementation
void MathInterface::registerInterface(boost::python::object& nspace) {
void MathInterface::registerInterface(py::module& scope, py::dict& globals)
{
// Add the Vector3 class
nspace["Vector3"] = boost::python::class_<Vector3>("Vector3", boost::python::init<double, double, double>())
.def(boost::python::init<const Vector3&>())
// greebo: Pick the correct overload - this is hard to read, but it is necessary
.def("x", static_cast<double& (Vector3::*)()>(&Vector3::x),
boost::python::return_value_policy<boost::python::copy_non_const_reference>())
.def("y", static_cast<double& (Vector3::*)()>(&Vector3::y),
boost::python::return_value_policy<boost::python::copy_non_const_reference>())
.def("z", static_cast<double& (Vector3::*)()>(&Vector3::z),
boost::python::return_value_policy<boost::python::copy_non_const_reference>())
.def("getLength", &Vector3::getLength)
.def("getLengthSquared", &Vector3::getLengthSquared)
.def("getNormalised", &Vector3::getNormalised)
.def("normalise", &Vector3::normalise)
.def("getInversed", &Vector3::getInversed)
.def("dot", &Vector3::dot<double>)
.def("angle", &Vector3::angle<double>)
.def("crossProduct", &Vector3::crossProduct<double>)
.def("max", &Vector3::max)
.def("min", &Vector3::min)
.def("isParallel", &Vector3::isParallel<double>)
// Most important operators
.def(boost::python::self + boost::python::self) // __add__
.def(boost::python::self - boost::python::self) // __sub__
.def(boost::python::self += boost::python::self)
.def(boost::python::self -= boost::python::self)
.def(boost::python::self < boost::python::self); // __lt__
;
py::class_<Vector3> vec3(scope, "Vector3");
vec3.def(py::init<double, double, double>());
vec3.def(py::init<const Vector3&>());

// greebo: Pick the correct overload - this is hard to read, but it is necessary
vec3.def("x", static_cast<double& (Vector3::*)()>(&Vector3::x), py::return_value_policy::reference);
vec3.def("y", static_cast<double& (Vector3::*)()>(&Vector3::y), py::return_value_policy::reference);
vec3.def("z", static_cast<double& (Vector3::*)()>(&Vector3::z), py::return_value_policy::reference);
vec3.def("getLength", &Vector3::getLength);
vec3.def("getLengthSquared", &Vector3::getLengthSquared);
vec3.def("getNormalised", &Vector3::getNormalised);
vec3.def("normalise", &Vector3::normalise);
vec3.def("getInversed", &Vector3::getInversed);
vec3.def("dot", &Vector3::dot<double>);
vec3.def("angle", &Vector3::angle<double>);
vec3.def("crossProduct", &Vector3::crossProduct<double>);
vec3.def("max", &Vector3::max);
vec3.def("min", &Vector3::min);
vec3.def("isParallel", &Vector3::isParallel<double>);
// Most important operators
vec3.def(py::self + py::self); // __add__
vec3.def(py::self - py::self); // __sub__
vec3.def(py::self += py::self);
vec3.def(py::self -= py::self);
vec3.def(py::self < py::self); // __lt__

// Register Vertex3f, which extends Vector3
nspace["Vertex3f"] = boost::python::class_<Vertex3f,
boost::python::bases<Vector3> >("Vertex3f", boost::python::init<>() )
.def(boost::python::init<const Vector3&>())
.def(boost::python::init<double, double, double>())
;
py::class_<Vertex3f, Vector3> vertex3f(scope, "Vertex3f");
vertex3f.def(py::init<>());
vertex3f.def(py::init<const Vector3&>());
vertex3f.def(py::init<double, double, double>());

// Add the Vector2 class
nspace["Vector2"] = boost::python::class_<Vector2>("Vector2", boost::python::init<double, double>())
.def(boost::python::init<const Vector2&>())
// greebo: Pick the correct overload - this is hard to read, but it is necessary
.def("x", static_cast<double& (Vector2::*)()>(&Vector2::x),
boost::python::return_value_policy<boost::python::copy_non_const_reference>())
.def("y", static_cast<double& (Vector2::*)()>(&Vector2::y),
boost::python::return_value_policy<boost::python::copy_non_const_reference>())
.def("getLength", &Vector2::getLength)
.def("getLengthSquared", &Vector2::getLengthSquared)
.def("dot", &Vector2::dot<double>)
.def("crossProduct", &Vector2::crossProduct<double>)
// Most important operators
.def(boost::python::self + boost::python::self) // __add__
.def(boost::python::self - boost::python::self) // __sub__
.def(boost::python::self += boost::python::self)
.def(boost::python::self -= boost::python::self)
.def(boost::python::self < boost::python::self); // __lt__
;
py::class_<Vector2> vec2(scope, "Vector2");
vec2.def(py::init<double, double>());
vec2.def(py::init<const Vector2&>());

// greebo: Pick the correct overload - this is hard to read, but it is necessary
vec2.def("x", static_cast<double& (Vector2::*)()>(&Vector2::x), py::return_value_policy::reference);
vec2.def("y", static_cast<double& (Vector2::*)()>(&Vector2::y), py::return_value_policy::reference);
vec2.def("getLength", &Vector2::getLength);
vec2.def("getLengthSquared", &Vector2::getLengthSquared);
vec2.def("dot", &Vector2::dot<double>);
vec2.def("crossProduct", &Vector2::crossProduct<double>);
// Most important operators
vec2.def(py::self + py::self); // __add__
vec2.def(py::self - py::self); // __sub__
vec2.def(py::self += py::self);
vec2.def(py::self -= py::self);
vec2.def(py::self < py::self); // __lt__

// Add the Vector4 class
boost::python::class_<Vector4> vector4Decl("Vector4", boost::python::init<double, double, double, double>());
py::class_<Vector4> vec4(scope, "Vector4");
vec4.def(py::init<double, double, double, double>());
vec4.def(py::init<const Vector4&>());

vector4Decl.def(boost::python::init<const Vector4&>())
// greebo: Pick the correct overload - this is hard to read, but it is necessary
.def("x", static_cast<double& (Vector4::*)()>(&Vector4::x),
boost::python::return_value_policy<boost::python::copy_non_const_reference>())
.def("y", static_cast<double& (Vector4::*)()>(&Vector4::y),
boost::python::return_value_policy<boost::python::copy_non_const_reference>())
.def("z", static_cast<double& (Vector4::*)()>(&Vector4::z),
boost::python::return_value_policy<boost::python::copy_non_const_reference>())
.def("w", static_cast<double& (Vector4::*)()>(&Vector4::w),
boost::python::return_value_policy<boost::python::copy_non_const_reference>())
.def("getVector3", static_cast<Vector3& (Vector4::*)()>(&Vector4::getVector3),
boost::python::return_value_policy<boost::python::copy_non_const_reference>())
.def("getProjected", &Vector4::getProjected)
.def("dot", &Vector4::dot<double>)
// Most important operators
.def(boost::python::self + boost::python::self) // __add__
.def(boost::python::self - boost::python::self) // __sub__
.def(boost::python::self += boost::python::self)
.def(boost::python::self -= boost::python::self)
;
// greebo: Pick the correct overload - this is hard to read, but it is necessary
vec4.def("x", static_cast<double& (Vector4::*)()>(&Vector4::x), py::return_value_policy::reference);
vec4.def("y", static_cast<double& (Vector4::*)()>(&Vector4::y), py::return_value_policy::reference);
vec4.def("z", static_cast<double& (Vector4::*)()>(&Vector4::z), py::return_value_policy::reference);
vec4.def("w", static_cast<double& (Vector4::*)()>(&Vector4::w), py::return_value_policy::reference);
vec4.def("getVector3", static_cast<Vector3& (Vector4::*)()>(&Vector4::getVector3), py::return_value_policy::reference);
vec4.def("getProjected", &Vector4::getProjected);
vec4.def("dot", &Vector4::dot<double>);
// Most important operators
vec4.def(py::self + py::self); // __add__
vec4.def(py::self - py::self); // __sub__
vec4.def(py::self += py::self);
vec4.def(py::self -= py::self);

// Add the Vector4 and Quaternion with the same interface
nspace["Vector4"] = nspace["Quaternion"] = vector4Decl;
scope.add_object("Quaternion", vec4);

// Declare AABB to python
nspace["AABB"] = boost::python::class_<AABB>("AABB", boost::python::init<>())
.def(boost::python::init<const Vector3&, const Vector3&>())
.def_readwrite("origin", &AABB::origin)
.def_readwrite("extents", &AABB::extents)
.def("isValid", &AABB::isValid)
.def("getRadius", &AABB::getRadius)
.def("includePoint", &AABB::includePoint)
.def("includeAABB", &AABB::includeAABB)
;
py::class_<AABB> aabb(scope, "AABB");
aabb.def(py::init<>());
aabb.def(py::init<const Vector3&, const Vector3&>());
aabb.def_readwrite("origin", &AABB::origin);
aabb.def_readwrite("extents", &AABB::extents);
aabb.def("isValid", &AABB::isValid);
aabb.def("getRadius", &AABB::getRadius);
aabb.def("includePoint", &AABB::includePoint);
aabb.def("includeAABB", &AABB::includeAABB);
}

} // namespace script
12 changes: 4 additions & 8 deletions plugins/script/interfaces/MathInterface.h
@@ -1,10 +1,9 @@
#ifndef _MATH_INTERFACE_H_
#define _MATH_INTERFACE_H_
#pragma once

#include <boost/python.hpp>
#include "iscript.h"

namespace script {
namespace script
{

// ========== Math objects ==========

Expand All @@ -13,10 +12,7 @@ class MathInterface :
{
public:
// IScriptInterface implementation
void registerInterface(boost::python::object& nspace);
void registerInterface(py::module& scope, py::dict& globals) override;
};
typedef std::shared_ptr<MathInterface> MathInterfacePtr;

} // namespace script

#endif /* _MATH_INTERFACE_H_ */

0 comments on commit 22d6b35

Please sign in to comment.