Feb 14, 2018 - Projects and Versions

Haven’t posted in a while. Well, really, no one reads my little blog so no one has missed my missives.

To catch up:

After doing some work on region simplification (for displaying OpenSimulator regions in a browser), I’ve been trying to create an OAR to other format converter. OAR files are the region archive format of OpenSimulator. The OAR file reading code is in C# (the native language of OpenSimulator ). I started thinking that the best output format would be GLTF since it was new and upcoming. There are conversion toolsets in the Cesium project and it looked like the browser world was moving there.

Well, I ended up writing my own GLTF format exporter and had it more-or-less working with ThreeJS.

Then, the GLTF standards group decided that the world needed a version 2 of the GLTF format. Over many months (and I mean MANY), the standard and then all of the tools in the pipeline converted from GLTFv1 to GLTFv2. Then there was the wait for the GLTF extensions to convert to version 2. As of this writing, I’m not sure all the tools have caught up.

It then occured to me that I could use an existing format conversion library to convert the OAR scene to many different formats. So I found Assimp that reads and writes many different 3D formats. One problem with that choice is that Assimp is a C++ library and, as mentioned above, I was working in C#.

An interface library was required so I found Assimp-net. Well, actually one of the forks of Assimp-net which had been updated recently. But it had been updated to the most recent Microsoft C# framework which, it turned out, was not yet supported by everything.

Sigh. It is frustrating spending time playing with tool versioning when I just wanted to do some 3D object conversion. It feels like I started the day trying to build a house. But, to build that house, I needed a hammer. So I needed to research what hammer options were available. To get the hammer option I needed, I had to then study forging and how to forge the type of hammer I needed. Finally, after weeks of researching hammers and forging and where to dig up the iron oar, I look up and there is still the empty lot where my house should be.

I’m shelving that project to let the tools mature a bit. In the mean time, it’s off to building robots!


Aug 15, 2017 - BulletSim Upgrade and Fixes

An update to BulletSim has been checked into the OpenSimulator that upgrades BulletSim with version 2.86 of the Bullet physics engine as well as fixing some known problems.

Mantis 8010 (“BulletSim does not always call collision events on collisions”) was caused by BulletSim not doing collision detection on all of the physics engine sub-steps. This meant that fast moving objects (like bullets) could bounce off of a target without reporting any collisions. For those into details, any OpenSimulator physics engine is called every tenth of a second to simulate the next tenth of a second of time. BulletSim internally steps 10 times within that tenth of a second to do a higher resolution physics simulation – a tenth of a second is a long simulation step but that’s the way OpenSimulator does it.

Mantis 8011 (“BulletSim fails to send land_collision messages on some terrain”) was caused by BulletSim computing terrain height differently than the mesh in the physics engine. So, an object on steep terrain could compute as underground to some code while appearing above ground in other code. BulletSim prevents physical objects from going underground by pushing them up when the do. This check would sometimes cause a falling object to float over terrain rather than colliding with the terrain.

The problem in Mantis 7132 (“Collisions stop for no apparent reason on BulletSim”) hasn’t been explicitly fixed. Still looking for that problem.

I found an additional problem that collision_end events don’t happen if the colliding object does an llDie() on its collision. For instance, a target object wouldn’t get a collision_end event for a bullet object that hits the target and does an llDie() on its collision. It looks like the ODE and ubODE physics engines don’t exhibit this problem because of the order that collisions are reported to the simulator. The fix is some code re-organization in SceneObjectPart.cs.

Still in the pipeline is the proper implementation of PhysicsShapeType and then physics engine implementation of raycast.


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.


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.


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.