Aug 7, 2017 - Bullet Version Upgrade and Build Tasks

Since the Bullet physics engine is distributed with OpenSimulator as a binary, I have to keep my library compatibility kind of old fashioned, That means I can’t use the latest-and-greatest Visual Studio nor the latest-and-greatest version of Linux. I’m building the Linux versions on Ubuntu 14.04 as that has been good with various shared library compatibilities. For Windows, I’m using Visual Studio 2012.

I have to build for both 32 bit and 64 bit Linux systems. Does anyone still use 32 bit?

The upgrade of the Bullet physics engine to v2.86 doesn’t seem to have any problems and I will start the OpenSimulator development branch (“BulletSim2017”) later today. There shouldn’t be any functional difference.

After thinking about the work to be done and talking to people, the major task list is getting longer:

  • Upgrade the underlying Bullet physics engine to version 2.86;
  • Fix the missing collision problem ;
  • CPU performance improvements (people mention high CPU usage with physical objects);
  • generate convex shapes if PhysicsShapeType is set to CONVEX;
  • Raycasting is not done in the physics engine.

Once I’m happy with the upgrade, I’ll create some test cases for collisions and CPU usages to track progress.

Comments

Aug 5, 2017 - Working on BulletSim

I’ve set aside time the next two weeks to work on BulletSim. As some of you might know, I am the original author of the BulletSim physics engine in OpenSimulator. While other projects have taken up most of my attention, there are some tweeks to BulletSim that are needed.

There are three things that I want to address the next weeks:

The first job is getting re-setting up the build environment. I have to use an old version of Visual Studio and an old version of Linux so the compiled C++ code DLL’s and SO’s will work on older versions of the operating systems.

When I start making source changes, I’ll create an OpenSimulator branch for testing.

Stay tuned.

Comments

May 29, 2017 - Simplifying Regions

One of the many problems with displaying OpenSimulator content in a web browser is that the WebGL interface doesn’t handle lots of draw operations well.

I have been using the Army Research Lab’s Atropia region OAR files for testing as it includes meshes as well as many shopping scripted objects.

The Atropia regions consist of nine 256x256 meter regions arranged in a 3 by 3 pattern. This table summerizes the basic content of the regions.

test88 00 01 02 10 11 12 20 21 22
Simple prims 19 109 3088 10 416 9317 13 2 4063 0
Sculpties 0 1 0 0 187 1986 0 0 4175 0
Mesh assets 0 0 2 0 47 213 0 0 0 0

Of the many approaches to making the scene easier to render, I started with merging meshes that share textures. I decided that I could partition the scene into two types of objects: static and non-static. “Static” objects are those with no scripts and no physics. This should be buildings and plants in the scene. “non-static” objects are those that either have physics enables or have a script that is waiting for touch or collisions.

The initial thought is that all static objects can be merged and have their meshes rearranged in any way while the non-static objects need to be kept as separatable objects. The next table shows a simple partitioning of the regions into these static and non-static objects. In this table, “meshes” is the count of individual meshes after prims have been converted into meshes for rendering (a single prim will convert into 6 or more face meshes).

test88 00 01 02 10 11 12 20 21 22
Static meshes 166 928 15995 44 2910 55398 95 15 17499 1
Static materials/textures 93/4 520/30 8141/81 8/3 1209/80 27402/637 44/11 5/3 16256/38 1/1
nonStatic meshes 0 0 5799 20 0 4993 0 0 120 0
nonStatic materials/textures 0/0 0/0 2671/37 8/3 0/0 1618/94 0/0 0/0 53/15 0/0

So, all the static meshes were combined into a set of rebuilt meshes each of which shared similar surface materials (and thus could use the same WebGL draw command). Each of the non-static objects has any common material meshes combined and the resulting numbers were:

test88 00 01 02 10 11 12 20 21 22
Rebuilt static meshes 12 128 801 7 375 4014 32 3 211 1
Rebuilt nonStatic meshes 0 0 654 6 0 857 0 0 33 0
Total WebGL draws 12 128 1055 13 375 4868 32 3 244 1
draws before rebuild 166 928 21794 64 2910 60391 95 15 17619 1

As you can see from the last rows, the rebuilding and merging of common surface materials significantly reduced the number of potential WebGL draw commands.

Merging common materials gets the number of draws within usability, there are still some problems:

  • even at 1000 draws, atropia02 still crashes ThreeJS and BabylonJS with out of memory errors;
  • materials with transparency (most commonly the plant sculpties) cannot be merged as most 3D renderers will Z-order transparent meshes but do not depth order the individual triangles within a mesh;

The above scene rebuild is mesh-centric. That is, the meshes are merged without thought as to what they belonged to (other than static and non-static). Since these scenes have many duplicated meshes (the bushes scattered around the scenes), another approach would be to use mesh instancing to reduce draws. This technique will be explored next.

Comments

Apr 16, 2017 - Javascript and Flatbuffers

I spent a while figuring out Flatbuffers and Javascript so I figured I’d pass on what I learned in a Note that explains how I got it to work. My problem was that I didn’t understand how Flatbuffers worked internally so my first implementation failed.

Check out JavaScript and Flatbuffers.

Comments

Apr 9, 2017 - Flatbuffers tables in tables

Forgot to push publish.

Besides having some family over to the house for dinner, today’s coding was even more Flatbuffers coding.

I’m in the trough of disillusionment with FlatBuffers.

For FlatBuffers, one writes a schema description of records. The tool then generates serialization and deserialization code for the target language. The coolness comes from the the streamlined deserialization which minimizes data reformatting and copying.

But the programming interface to these serialization routines is a tad clunky. Firstly, you never know what type of serialization interface it is going to generate. Sometimes it will generate a single create call to build a structure and sometimes it generates a ‘start’ and ‘end’ function with ‘add’ functions for the fields. It took me a while to realize the interface difference comes between ‘struct’ and ‘table’ definitions. Another factoid that is not explained in the documentation.

Another thing I’m learning is that the serialization interface gets complex if one defines a protocol with ‘table’s inside ‘table’s. Using the schema, it is easy to define a record that includes several tables. The problem comes in the complexity of the record generation code – table generation code embedded in table generation code embedded in table generation code. The make-a-record subroutine becomes long and complex. Additionally, if a field is ever added to a table, code in several different places will need modification.

It would be nice if the code generator created some higher level code.

Comments