1
\$\begingroup\$

I use Google V8 engine to embed Javascript into my game for scripting. As interface to my native code, I already registered some C++ functions to the scripting context.

In the native code, I make intense use of the C++ library GLM which adds vector types and geometry functions. The naming is in a style that may be known from shader code, for example vec3, uvec2, normalize(), length(), and much more.

Now I would like to make these types available in scripting. That would be useful because of both, the geometry functions and the vector types. Especially, I want to use the vector types as parameters in the C++ functions I mapped to the Javascript context. At the moment I'm using arrays like float[3] instead of the vectors like vec3.

So I am looking for possible ways to bring GLM functionality into Javascript. This is what I can think of.

  • Create the most important types by hand, either in a Javascript file or injected from C++ code using object templates. Unfortunately, I cannot do this for all of the many functions in GLM. But it would better than nothing.
  • There might already be a GLM port of Javascript, which I haven't found on the internet.
  • I could pick a different geometry library for use in Javascript. For bound C++ functions, I'd have to translate their types into GLM ones then.
  • What can you think of...

Maybe there is a cool way to all the functionality of GLM over to Javascript. Are there things like C++ to Javascript source code converters? Or automatically binding a whole C++ namespace to scripting? I don't think that is possible. But Javascript is such a dynamic language, there must be a way to make the GLM types available for it.

What ways are there for making the vector types, and preferably also the useful geometry helper functions, available in scripting?

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

In V8 you can wrap your own, custom C++ classes expose them to JavaScript and have V8 take care of destructing the instance once the corresponding JS object gets GC'd.

But you still have to write your methods in a style like this:

Handle<Value> Vector::add(const Arguments& args) {

    Vector *vector = WrappedClass::unwrap<Vector>(args.This());
    if (args.Length() == 2) {
        vector.x += args[0]->DoubleValue();
        vector.y += args[1]->DoubleValue();

    } else {
        // throw a exception or something
    }

    return args.This();

}

Now as you can see there's no trivial way to just take the C++ class and put it into JS. You either have to write some custom binding generator and generate the bindings pre-compile time, or you write it manually. You'll also have to handle cases where operator overloading happens, or where a method has multiple signatures.

Given all of this it would be not much more trouble to put the library through Emscripten and write bindings for that and then use the compiled JS code directly.

As for performance, I'm pretty sure that writing pure JS will probably be faster for 90% of the cases (except areas where you can do a lot of magic through raw pointers and memory access) because all those wrappers will introduce a lot of indirection.

Emscripten could be quite decent in terms of performance, but I assume it won't be trivial to set up.

So sadly, there's no easy way to expose all of the functionality, if you really just need a robust vector library for JS, you could take a look at Sylvester, but this of course won't give you the benefits of GLM's naming conventions. Also, I'd be careful and have a look at Sylvester's code base, just to make sure you know how much object creation / garbage collection you can expect from heavy use.

For reference you can check out two of my dead side projects in which I used V8 for scripting:

\$\endgroup\$
1
  • \$\begingroup\$ Thanks a lot. I may end up add only the types to the Javascript context from C++ and rewrite the functions of GLM in pure Javascript. There is no #include equivalent, is it? By the way, my binding code for handling multiple function signatures becomes quite messy often. Do you know a good way to handle this? Okay, I think I should open another question for this. \$\endgroup\$
    – danijar
    Commented Aug 8, 2013 at 15:09
0
\$\begingroup\$

On JavaScript side you can use glMatrix. (Take a look on this presentation: http://media.tojicode.com/sfjs-vectors/#1 ). On C++ side you can use GLM as usaual. You can cast pointers to floats to GLM types. For example:

float fArray[3];
glm::vec3& v = *((glm::vec3*) fArray);
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .