Did not mean to commit/push the current state of master. But rather than
mess up source control history with a force push, I'll just try to hurry
to a stable point.
Hopefully without unintentional changes to functionality. This renames header
files to .hpp, imposes a gltf/raw/fbx directory structure, extracts standalone
chunks of Fbx2Raw into distinct files, and undoes some particularly egregious
mistakes from when I knew even less C++ than I do now.
This is in anticipation of implementing 3ds Max's "Physical Material".
The condense operation recreates the vectors of surfaces, materials,
textures and vertices so as to exclude anything that isn't referenced
explicitly by a triangle. In the process, we must take care that
references from other properties are cleared out.
This fixes the case when a node references a mesh by id, and then the
mesh is deleted because no triangle references. TODO: go through other
properties and make sure the same problem doesn't exist there.
It is also possible that these vectors should be replaced by maps, at
least for the elements that (now) have unique IDs.
A mesh with a single (skinning) deformer which had zero clusters would
erroneously register as skinned, leading GetRoodNode() to an assertion
failure. Fixed.
We're still gunshy from our previous attempts at coming up with metalilc
and roughness values from diffuse/specular/shininess, but this should be
safe: a high shininess means a low roughness, and vice versa.
The FBX SDK looks for our textures and often finds them. It helpfully
tells us exactly where they are. Let's not throw that information away
and demand that the textures only exist in precisely the folders we are
aware of.
Because we make a best-effort attempt to convert materials on the old
form -- like :ambert and Phong -- to PBR materials, it can be beneficial
to the consumer of the asset to know if the asset was intentionally
authored as PBR, or if it was a conversion.
The precise details of this information is specific to the intersection
of FBX and glTF, so we're not going to bother proposing extensions; we
just drop something into the extras field, e.g.
"materials": [
{
"name": "Troll_Water",
"alphaMode": "OPAQUE",
"extras": {
"fromFBX": {
"shadingModel": "Metallic/Roughness",
"isTruePBR": true
}
},
// ... and so on.
The possible values for shadingModel are:
"<unknown>"
"Constant"
"Lambert"
"Blinn"
"Phong"
"Metallic/Roughness"
Currently isTruePBR is true for the final entry, false for the other.
However, we may well add more PBR shading models in the future, so if
you intend to use this feature to look for true PBR, use the derived
property.
Now that we're writing both 16-bit and 32-bit integers, it's starting to
matter a little more how we slam even scalars into memory. This is maybe
not the fastest way to accomplish this, and I'm not crazy about the way
GLType works in general, but it does have the virtues of clarity and
expediency.
By oversight we had not included occlusionTexture in the core
MaterialData. While we're at it, bake occlusion into the red channel of
the merged metallic/roughness texture.
There seem to be few constraints on what values FBX properties can take. By contrast, glTF constrains e.g. common material factors to lie in [0, 1]. We take a simple approach and just clamp.
Previous to this, a PNG that was on RGBA format would cause its
corresponding texture to be flagged as transparent. This is very
silly. We now iterate over the bytes, and if any is not 255, THEN
there's alpha.
This was way overdue. Breaking up large meshes into many 65535-vertex
primitives can save a few bytes, but it's really a lot of complication
for minor benefit.
With this change the user can force short or long indices, and the
default is to use shorts for smaller meshes and longs for longer.
- KHR_materials_common never had a real life in the glTF 2.0 world. One
day we may see a new extension for Phong/Blinn/Lambert.
- PBR_specular_glossiness is a poor fit for PBS StingRay (the only real
source of PBR we have) and has no advantage over PBR_metallic_roughness.
- The conversion we were doing for traditional materials to PBR made no
sense. Revert to a very simple formula: diffuse -> baseColor, simple
reasonable constants for metallic & roughness.
The user can now ask for normals to be computed NEVER (can easily cause
broken glTF if the source isn't perfect), MISSING (when the mesh simply
lacks normals), BROKEN (only emptuy normals are replaced), or
ALWAYS (perhaps if the normals in the source are junk).
I stole expressions from Gary Hsu's PBR conversion routines here:
3606e79717/extensions/Khronos/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows/js/three.pbrUtilities.js
which is experimental enough as it is, but I had gone further into the
domain of madness and uses this with *old* diffuse/specular values, not
PBR specular/glossness.
As a result a lot of old content was coming up with 100% metal values
quite often, which in turn means completely ignoring diffuse when
assembling a new base colour...
I should rip out this whole conversion. But not just now...
It's technically valid for e.g. scale to have a zero dimension, which in
turn wreaks havoc on the rotation quaternion we get from the FBX SDK.
The simplest solution is to just leave any T/R/S vector out of the glTF
if it has any NaN component.
Be more flexible about reading various input formats (most especially
varying numbers of channels), and stop outputting RGBA PNGs for textures
that don't need it.
I'm not sure JPG generation ever worked right. But now it does.
Fix the naming issues. Now the nodes are identified by pNode->GetUniqueID(), instead of its name. All dictionaries and references to nodes are replaced by its id, instead of its name.