Forum Archive

SystemError: bad argument to internal function

Cethric

Can someone please point out to me what is wrong with this code.

# coding: utf-8
import objc_util
from objc_util import *
import ctypes
import euclid
import urlparse
import time
import ui

PHYSICS_DIR = __file__.replace("__init__.py", "")
BULLET_CODE = os.path.join(os.path.join(PHYSICS_DIR,"ammo.js"))
if os.path.exists(BULLET_CODE):
    with open(BULLET_CODE, "rb") as f:
        AMMO = f.read()
else:
    ammo_url = "https://raw.githubusercontent.com/kripken/ammo.js/master/builds/ammo.js"
    print "No Bullet engine (ammo.js file) found"
    print "Downloading one from '%s'" % ammo_url
    import urllib2
    try:
        f = urllib2.urlopen(ammo_url)
        AMMO = f.read()
        with open(BULLET_CODE, "wb") as r:
            r.write(AMMO)
    finally:
        f.close()
    print "ammo.js successfully downloaded"

BULLET_HTML = '''<!DOCTYPE html>
<html>
    <head>
        <title> Bullet Physics Hub </title>
        <script>
            function send_to_python(name, param) {
                var iframe = document.createElement("IFRAME");
                iframe.setAttribute("src", 'python://method?name=' + name + "&param=" + param);
                document.documentElement.appendChild(iframe);
                iframe.parentNode.removeChild(iframe);
                iframe = null;
            }

            console.log = function(log) {
                send_to_python("ios_log", log);
            }
            console.debug = function(log) {
                send_to_python("ios_debug", log);
            }
            console.info = function(log) {
                send_to_python("ios_info", log);
            }
            console.warn = function(log) {
                send_to_python("ios_warn", log);
            }
            console.error = function(log) {
                send_to_python("ios_error", log);
            }
            console.alert = function(prompt, msg) {
                send_to_python("ios_alert", prompt + ":" + msg);
            }
            window.onerror = (function(error, url, line, col, errorobj) {
               console.error(error + " at " + line + ":" + col);
            });
            console.log("logging activated");
            print = (function(arg) {
                send_to_python('ios_print', arg);
            });

            get_position = (function(id, pos) {
                send_to_python('_get_position', id + '#' + pos)
            })

            get_rotation = (function(id, pos) {
                send_to_python('_get_rotation', id + '#' + pos)
            })
        </script>
    </head>
    <body>
        <p> Bullet Physics test </p>
    </body>
</html>'''

PHYSICS_WORLD_LOAD = '''
var collisionConfiguration = new Ammo.btDefaultCollisionConfiguration();
var dispatcher = new Ammo.btCollisionDispatcher(collisionConfiguration);

var maxProxies = 16384;
var aabbmin = new Ammo.btVector3(-1000,-1000,-1000); // world size
var aabbmax = new Ammo.btVector3(1000,1000,1000);
var overlappingPairCache = new Ammo.btAxisSweep3(aabbmin, aabbmax, maxProxies);

var solver = new Ammo.btSequentialImpulseConstraintSolver();
var dynamicsWorld = new Ammo.btDiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration);
dynamicsWorld.setGravity(new Ammo.btVector3(0, -9.8, 0));

var bodies = [];

var groundShape = new Ammo.btBoxShape(new Ammo.btVector3(50, 50, 50));
var groundTransform = new Ammo.btTransform();
groundTransform.setIdentity();
groundTransform.setOrigin(new Ammo.btVector3(0, -56, 0));

(function() {
  var mass = 0;
  var isDynamic = mass !== 0;
  var localInertia = new Ammo.btVector3(0, 0, 0);

  if (isDynamic)
    groundShape.calculateLocalInertia(mass, localInertia);

  var myMotionState = new Ammo.btDefaultMotionState(groundTransform);
  var rbInfo = new Ammo.btRigidBodyConstructionInfo(mass, myMotionState, groundShape, localInertia);
  var body = new Ammo.btRigidBody(rbInfo);

  dynamicsWorld.addRigidBody(body);
  bodies.push(body);
})();
'''

ADD_SPHERE = '''
(function() {
  var colShape = new Ammo.btSphereShape(%f);

  var startTransform = new Ammo.btTransform();
  startTransform.setIdentity();

  var mass = %f;
  var isDynamic = mass !== 0;
  var localInertia = new Ammo.btVector3(0, 0, 0);

  if (isDynamic) {
    colShape.calculateLocalInertia(mass, localInertia);
  }

  startTransform.setOrigin(new Ammo.btVector3(%f, %f, %f));

  var myMotionState = new Ammo.btDefaultMotionState(startTransform);
  var rbInfo = new Ammo.btRigidBodyConstructionInfo(mass, myMotionState, colShape, localInertia);
  var body = new Ammo.btRigidBody(rbInfo);

  dynamicsWorld.addRigidBody(body);
  bodies.push(body);
})();
var l = bodies.length - 1;
l
'''

ADD_BOX = '''
(function() {
  var size = %f;
  var colShape = new Ammo.btBoxShape(new Ammo.btVector3(size, size, size));

  var startTransform = new Ammo.btTransform();
  startTransform.setIdentity();

  var mass = %f;
  var isDynamic = mass !== 0;
  var localInertia = new Ammo.btVector3(0, 0, 0);

  if (isDynamic) {
    colShape.calculateLocalInertia(mass, localInertia);
  }

  startTransform.setOrigin(new Ammo.btVector3(%f, %f, %f));

  var myMotionState = new Ammo.btDefaultMotionState(startTransform);
  var rbInfo = new Ammo.btRigidBodyConstructionInfo(mass, myMotionState, colShape, localInertia);
  var body = new Ammo.btRigidBody(rbInfo);

  dynamicsWorld.addRigidBody(body);
  bodies.push(body);
})();
var l = bodies.length - 1;
l
'''

ADD_SHAPE = '''
(function() {
  var colShape = _shape;

  var startTransform = new Ammo.btTransform();
  startTransform.setIdentity();

  var mass = %f;
  var isDynamic = mass !== 0;
  var localInertia = new Ammo.btVector3(0, 0, 0);

  if (isDynamic) {
    colShape.calculateLocalInertia(mass, localInertia);
  }

  startTransform.setOrigin(new Ammo.btVector3(%f, %f, %f));

  var myMotionState = new Ammo.btDefaultMotionState(startTransform);
  var rbInfo = new Ammo.btRigidBodyConstructionInfo(mass, myMotionState, colShape, localInertia);
  var body = new Ammo.btRigidBody(rbInfo);

  dynamicsWorld.addRigidBody(body);
  bodies.push(body);
})();
var l = bodies.length - 1;
l
'''

GET_POSITION = '''
var id = %s;
var body = bodies[id];
if (body.getMotionState()) {
    var trans = new Ammo.btTransform();
    body.getMotionState().getWorldTransform(trans);
    get_position(id, [trans.getOrigin().x(), trans.getOrigin().y(),trans.getOrigin().z()]);
}
'''

GET_ROTATION = '''
var id = %s;
var body = bodies[id];
if (body.getMotionState()) {
    var trans = new Ammo.btTransform();
    body.getMotionState().getWorldTransform(trans);
    get_rotation(id, [trans.getRotation().w(), trans.getRotation().x(),trans.getRotation().y(), trans.getRotation().z()]);
}
'''

class Bullet(object):
    def __init__(self):
        self.setup = False
        self.wv = ui.WebView()
        self.wv.delegate = self
        self.wv.load_html(BULLET_HTML)
        self.frame = (0,0,0,0)
        self.ids = []
        self.objdata = {}

        self.can_check = False
        # self.wv.present("sheet")

    def webview_should_start_load(self, webview, url, nav_type):
        r = not 'python' in url
        if not r:
            url = url.replace("python://method?", "")
            qs = urlparse.parse_qs(url)
            funcname = qs['name'][0]
            args = qs['param'][0]
            func = None
            try:
                func = getattr(self, funcname)
            except Exception as e:
                print "Function", funcname, "Does not exist"
            if func:
                func(args)
        return r

    def ios_log(self, args):
        print "BULLET-LOG:", args

    def ios_print(self, args):
        print "BULLET:", args

    def ios_error(self, args):
        print "BULLET-ERROR:", args

    def _get_position(self, args):
        args = args.split("#")
        self.objdata[int(args[0])][0] = [float(x) for x in args[1].split(",")]
        self.can_check = True

    def _get_rotation(self, args):
        args = args.split("#")
        self.objdata[int(args[0])][1] = [float(x) for x in args[1].split(",")]
        self.can_check = True

    def webview_did_finish_load(self, webview):
        if not self.setup:
            self.wv.evaluate_javascript(AMMO)
            self.wv.evaluate_javascript(PHYSICS_WORLD_LOAD)
            self.setup = True
        print "Functions can be called now"

    def webview_did_fail_load(self, webview, error_code, error_msg):
        print error_code, error_msg

    def add_object(self, vert, mass=1, pos=[0,0,0], convex=False):
        tris = len(vert) / 3
        if convex:
            self.wv.evaluate_javascript("var _shape = new Ammo.btConvexHullShape();")
            for x in range(0, tris, 3):
                v = vert[x:x+3]
                self.wv.evaluate_javascript("_shape.addPoint(new Ammo.btVector3(%f, %f, %f));" % (v[0], v[1], v[2]))
        else:
            self.wv.evaluate_javascript("var _mesh = new Ammo.btTriangleMesh();")
            for x in range(0, tris, 9):
                v = vert[x:x+9]
                (x1,y1,z1) = v[0:3]
                (x2,y2,z2) = v[3:6]
                (x3,y3,z3) = v[6:9]
                self.wv.evaluate_javascript("_mesh.addTriangle(new Ammo.btVector3(%f, %f, %f), new Ammo.btVector3(%f, %f, %f), new Ammo.btVector3(%f, %f, %f))" % tuple(v))
            self.wv.evaluate_javascript("var _shape = new Ammo.btBvhTriangleMeshShape(_mesh, true);")
        oid = self.wv.evaluate_javascript(ADD_SHAPE % (mass, pos[0], pos[1], pos[2]))
        self.ids.append(oid)
        self.objdata[int(oid)] = [(0,0,0), (0,0,0,0)]
        return oid

    def add_sphere(self, mass=1, pos=[0,0,0], radius=1):
        oid = self.wv.evaluate_javascript(ADD_SPHERE % (radius, mass, pos[0], pos[1], pos[2]))
        self.ids.append(oid)
        self.objdata[int(oid)] = [(0,0,0), (0,0,0,0)]
        return oid

    def add_box(self, mass=1, pos=[0,0,0], size=1):
        oid = self.wv.evaluate_javascript(ADD_BOX % (size, mass, pos[0], pos[1], pos[2]))
        self.ids.append(oid)
        self.objdata[int(oid)] = [(0,0,0), (0,0,0,0)]
        return oid

    def step_simulation(self, step, maxSubStep=1, fixTimeStep=1/60.0):
        start = time.clock()
        self.wv.evaluate_javascript("dynamicsWorld.stepSimulation(%f, %f, %f)" % (step, maxSubStep, fixTimeStep))
        end = time.clock()
        #print "step_simulation", end - start

    def get_object_pos(self, i=0):
        start = time.clock()
        i = int(i)
        vpos = euclid.Vector3()
        if not int(i) in self.objdata:
            return vpos

        def get_p():
            self._get_object_pos(i)
        ui.delay(get_p, 0.0)
        # self.can_check = False
        # while not self.can_check:
        #     pass
        pos = self.objdata[int(i)][0]
        if not len(pos) == 3:
            return vpos
        vpos.x = pos[0]
        vpos.y = pos[1]
        vpos.z = pos[2]
        end = time.clock()
        # print "get_object_pos", end - start
        return vpos

    def _get_object_pos(self, i):
        self.wv.evaluate_javascript(GET_POSITION % i)

    def get_object_rot(self, i=0):
        start = time.clock()
        i = int(i)
        qrot = euclid.Quaternion()
        if not int(i) in self.objdata:
            return qrot

        def get_p():
            self._get_object_rot(i)
        try:
            ui.delay(get_p, 0.0)
        except:
            get_p()

        # self.can_check = False
        # while not self.can_check:
        #     pass

        rot = self.objdata[int(i)][1]
        if not len(rot) == 4:
            return qrot
        qrot.w = rot[0]
        qrot.x = rot[1]
        qrot.y = rot[2]
        qrot.z = rot[3]
        end = time.clock()
        # print "get_object_rot", end - start
        return qrot

    def _get_object_rot(self, i):
        self.wv.evaluate_javascript(GET_ROTATION % i)

    def set_object_pos(self, i, pos):
        self.wv.evaluate_javascript("")

PhysicsWorld = Bullet()
while not PhysicsWorld.setup:
    pass

__all__ = ['PhysicsWorld']

if __name__ == "__main__":
    p = PhysicsWorld
    p.add_sphere(1, [0,20,0])
    import OpenGLES.Util.Model as Model
    m = Model.XMLModel("../../test_model.xml")
    for x in range(0, 0, 4):
        for y in range(0, 0, 4):
            for z in range(0, 0, 4):
                i = p.add_object(m.frames[m.frame], 10, [x,y,z])
    for _ in range(0, 1):
        p.step_simulation(1/60.0, 10)
        for i in p.ids:
            pos = p.get_object_pos(i)
            rot = p.get_object_rot(i)
            mat = euclid.Matrix4()
            mat.translate(pos.x, pos.y, pos.z)
            mat = mat * rot.get_matrix()
            print i, mat 

Note this uses my OpenGLES repo however it is not essential (just to test adding ConvexHull shapes and TriangleMesh Shapes.)

Webmaster4o

Is this helpful?

Webmaster4o

It does appear to be a problem with pythonista, the path points to an Xcode file.
@omz needs to fix this, I think.

Cethric

Sorry for not pointing this out earlier but this is actually the physics module of OpenGLES/Util/Physics/__init__.py. However it is my local copy not the one that is online (yet).

I will try what was suggested on stackoverflow

Thanks for the infomation

EDIT:
Resolved -> changed

def get_r():
    self._get_object_rot(i)

to

def get_r(self=self):
    self._get_object_rot(i)

Worked
Thanks again

Webmaster4o

Awesome.