Scene and Objects

The scene files are changing once again. The progression so far has only been from XML files to json, with changes to object behavior to better align the two. Essentially I want everything serializable for saving state between files.

Right now, the json file just contains a bunch of fields to specify how to load a mesh. Here's an example:

{
	"name": "cylinder scene",
	"meshes": [
		{
			"name": "cylinder",
			"description": "5 bone cylinder",
			"path": "../../data/models/cylinder",
			"skeletonFile": "cylinderskeleton.dae",
			"meshFile": "cylinder.obj",
			"tfType": "mat4",
			"skinning": {
				"load": [ "heatmap-0.45.weights" ],
				"methods": [ "ir" ]
			},
			"attachment": {
				"methods": [ "DirectProjection" ]
			}
		}
	]
}

I'm used to tweaking this file by hand, then reloading the program. But the last few overhauls made me outgrow this approach (read: I have a better UI that will be faster than this), so instead I'm interested in doing it the "right" way. I'm interested in a file storage system that:

  • maintains a directory for data storage. Textures, skin weights, UV sets, and animations would all be located here. Currently an input mesh knows its root folder ("path" in the above json) so it can load files relative to it. I want to do the same thing for the entire scene's data.
  • is binary-formatted. I'm working with meshes, which means lots of sequential data of a known size. Loses human readability, but I'm OK with that. The documentation will likely include a schema for parsing the scene file if necessary. Why not just stick with json text and list out the relevant binary files to load? Well, that makes file history harder to control. I think it's still OK to have the mesh and skeleton data (skin weights, animations, UVs, etc.) exportable and importable to their own binary format for reuse, but the general scene file should provide this information on its own.
  • preserves object state. Deform objects are responsible for changing behavior on meshes and skeletons. They're applied in order of creation and generally support undo/redo operations. Serializing these would allow me to save out command history, but I'm not convinced I want to copy Maya that much just yet. To have the current state preserved would be enough for iterative animation development. Reminder that the software's goals include supporting fast and easy exploration of ideas
  • I use a lot of smooth splines created by input device position (list of 2D points on desktop, or 3D points in VR, possibly filtered down with RDP, then chained smoothly together as a series of Bézier curves), and I want them available in between sessions. Or at least, I want the abstraction that they ultimately provide available in between sessions.
  • Flexible parsing. I want it to handle gradual changes to the format gracefully. An old scene file should still load if it doesn't have something a new parser expects.

Let's warm up with some of the types we care most about storing

  • Mesh
  • numVertices (size_t), followed by that many MeshVertex values representing the mesh vertices at bind
    • MeshVertex: position (vec3), normal(vec3), and uv(vec2). Ordered by index
  • numFaces (size_t), followed by that many uivec3 representing the mesh faces
  • SkinWeights
  • name (string), numVertices (size_t), followed by that many SkinWeight (indices (ivec4), weights (vec4))
  • SkeletonAttachment
  • name (string), mesh(Mesh), and binding (SkeletonBinding)
  • SkeletonBinding:
  • numVertices (size_t), followed by that many VertexAttachment (boneIndices (ivec2), t (vec2))
  • Skeleton
  • numJoints (size_t), followed by output of the root Transform. Each one processes itself, followed by its children.
    • Transform:
      • name (string)
      • color (vec4)
      • parent index (int) -1 if no parent
      • translation (vec3): bind translation
      • rotation (quaternion): bind rotation
      • scale (vec3): bind scale
      • numChildren (size_t), followed by that many child indices (int)