I imported an FBX model, then when I try to run raycaster.intersectObject on it, I get:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'side')
at checkIntersection (modules.js?hash=5362f5cdc7b6201ffad984d49b05ef801a326b32:119257:16)
at checkBufferGeometryIntersection (modules.js?hash=5362f5cdc7b6201ffad984d49b05ef801a326b32:119339:23)
at Mesh.raycast (modules.js?hash=5362f5cdc7b6201ffad984d49b05ef801a326b32:119201:23)
at intersectObject (modules.js?hash=5362f5cdc7b6201ffad984d49b05ef801a326b32:26018:10)
Because in checkIntersection the material parameter receives undefined due to Mesh receiving undefined when accessing const groupMaterial = material[ group.materialIndex ]; and passing that in, where group.materialIndex is -1 which is an invalid array index.
Yeah, checkIntersection needs to account for the fact that material can be undefined, because the most important thing is the geometry.
It should simply assume no back face culling in case there’s no material, because there’s no way to otherwise know the sidedness.
Do not read this if you don't like TypeScript
TypeScript prevents these sorts of silly mistakes.
The type of the material parameter for checkIntersection would have | undefined and would cause a type error inside the function, or it would not have | undefined and a type error would happen at the call site, and either way the silly mistake would be caught. etc.
if ( material && ( material.side === BackSide ) ) {
intersect = ray.intersectTriangle( pC, pB, pA, true, point );
} else {
intersect = ray.intersectTriangle( pA, pB, pC, material ? material.side !== DoubleSide : false, point );
}
Yeah, not sure. All I did was import the FBX model with FBXLoader, then cast at it.
Despite that though, strictly requiring a material is debatable, because raycasting mainly depends on intersecting geometry. I think material can be considered more as a hint.
I can see in the debugger that the loader actually extracts negative material indices (-1) from the FBX asset. Unfortunately, I’m not familiar with FBX so I can’t tell you what such definitions mean. However, FBXLoader does not expect them.
It shouldn’t have any negative indices. If it does, then either:
there’s a problem with your model
there’s a problem in the parser
I should have added a third possibility: a problem in the exporter. I expect that’s the issue here, unless things have changed in the last year or two, the Cinema4d FBX exporter is really buggy. You could try manually editing the FBX file to change any -1 to a 0 and see if that gives the correct result. I would hesitate to add that as a fix to the loader though because I don’t think it’s valid FBX and probably can’t be expected to give correct results in every case.
I know we wish all programs exported FBX the same way, but the reality is a major program exports indices with -1 values.
I watched the designer choose parts of those simple models above, simply pick a different color for each part, then export the model as FBX. There’s not much a designer can do to fix that.
The reality is a major program (Cinema4d) exports FBX files with a large number of problems, not just this one. While working on the FBXLoader I did try to take a pragmatic approach and it already does handle many cases like this even though they are technically incorrect. However, towards the end nearly all the remaining problems were coming from models exported by the buggy Cinema4d exporter and I was finding that fixing one model often resulted in breaking other (correct) models and I was having to tediously check each fix against 50 or so models. I also don’t use Cinema4d so there wasn’t much motivation for me to work on bug fixes for it.
The fix for this particular bug doesn’t seem like it would break other models, and if you find that setting the negative indices to zero (or perhaps they wrap around to the end of the array?) then by all means please do make a PR with a fix.
I also might phrase this as expensive well-known product has had a buggy FBX exporter for years and doesn’t seem to have made any steps to fix it - even though they are presumably using the FBX SDK and should have a much easier time than we do since we have to reverse engineer the proprietary spec. Why should the onus be on us open source devs working for free to support something when the company selling a product for $4000 won’t fix things on their end?
well it has been 5 years, so I did not even remember that thread. looking at it now, it seems that -1 index could maybe mean that there was no material assigned to that part of the geometry? I mean, just scroll down and look at collada version.
I guess it would be nice if 3js could just not render parts of the geometry where material index is invalid without throwing any error, but they are unlikely to care about this case.
Generally speaking, BufferGeometry .groups and group materials have been a disproportionate obstacle for maintenance and support in various three.js APIs. Invalid material indices are not the only related trouble cases. I would suggest avoiding geometry.groups or multi-material meshes, and using separate meshes — optionally sharing the same vertex attributes and different indices — instead.
Looking forward — be aware that groups are not supported in WebGPURenderer and there are no plans to implement them there. See:
Yeah, if I was working on the FBXLoader now I would probably implement this by splitting multi material meshes up into separate meshes. I think that’s what the GLTFLoader does, is that right?