Skip to content

Commit ad37aab

Browse files
authored
[Fix] Fix glb-parser for mesh without positions (playcanvas#2965)
1 parent 828ea76 commit ad37aab

File tree

1 file changed

+87
-77
lines changed

1 file changed

+87
-77
lines changed

src/resources/parser/glb-parser.js

Lines changed: 87 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,10 @@ var cloneTextureAsset = function (src) {
336336

337337
var createVertexBufferInternal = function (device, sourceDesc, disableFlipV) {
338338
var positionDesc = sourceDesc[SEMANTIC_POSITION];
339+
if (!positionDesc) {
340+
// ignore meshes without positions
341+
return null;
342+
}
339343
var numVertices = positionDesc.count;
340344

341345
// generate vertexDesc elements
@@ -629,7 +633,6 @@ var createMesh = function (device, gltfMesh, accessors, bufferViews, callback, d
629633

630634
var primitiveType, vertexBuffer, numIndices;
631635
var indices = null;
632-
var mesh = new Mesh(device);
633636
var canUseMorph = true;
634637

635638
// try and get draco compressed data first
@@ -717,94 +720,98 @@ var createMesh = function (device, gltfMesh, accessors, bufferViews, callback, d
717720
primitiveType = getPrimitiveType(primitive);
718721
}
719722

720-
// build the mesh
721-
mesh.vertexBuffer = vertexBuffer;
722-
mesh.primitive[0].type = primitiveType;
723-
mesh.primitive[0].base = 0;
724-
mesh.primitive[0].indexed = (indices !== null);
723+
var mesh = null;
724+
if (vertexBuffer) {
725+
// build the mesh
726+
mesh = new Mesh(device);
727+
mesh.vertexBuffer = vertexBuffer;
728+
mesh.primitive[0].type = primitiveType;
729+
mesh.primitive[0].base = 0;
730+
mesh.primitive[0].indexed = (indices !== null);
731+
732+
// index buffer
733+
if (indices !== null) {
734+
var indexFormat;
735+
if (indices instanceof Uint8Array) {
736+
indexFormat = INDEXFORMAT_UINT8;
737+
} else if (indices instanceof Uint16Array) {
738+
indexFormat = INDEXFORMAT_UINT16;
739+
} else {
740+
indexFormat = INDEXFORMAT_UINT32;
741+
}
725742

726-
// index buffer
727-
if (indices !== null) {
728-
var indexFormat;
729-
if (indices instanceof Uint8Array) {
730-
indexFormat = INDEXFORMAT_UINT8;
731-
} else if (indices instanceof Uint16Array) {
732-
indexFormat = INDEXFORMAT_UINT16;
733-
} else {
734-
indexFormat = INDEXFORMAT_UINT32;
735-
}
743+
// 32bit index buffer is used but not supported
744+
if (indexFormat === INDEXFORMAT_UINT32 && !device.extUintElement) {
736745

737-
// 32bit index buffer is used but not supported
738-
if (indexFormat === INDEXFORMAT_UINT32 && !device.extUintElement) {
746+
// #ifdef DEBUG
747+
if (vertexBuffer.numVertices > 0xFFFF) {
748+
console.warn("Glb file contains 32bit index buffer but these are not supported by this device - it may be rendered incorrectly.");
749+
}
750+
// #endif
739751

740-
// #ifdef DEBUG
741-
if (vertexBuffer.numVertices > 0xFFFF) {
742-
console.warn("Glb file contains 32bit index buffer but these are not supported by this device - it may be rendered incorrectly.");
752+
// convert to 16bit
753+
indexFormat = INDEXFORMAT_UINT16;
754+
indices = new Uint16Array(indices);
743755
}
744-
// #endif
745756

746-
// convert to 16bit
747-
indexFormat = INDEXFORMAT_UINT16;
748-
indices = new Uint16Array(indices);
757+
var indexBuffer = new IndexBuffer(device, indexFormat, indices.length, BUFFER_STATIC, indices);
758+
mesh.indexBuffer[0] = indexBuffer;
759+
mesh.primitive[0].count = indices.length;
760+
} else {
761+
mesh.primitive[0].count = vertexBuffer.numVertices;
749762
}
750763

751-
var indexBuffer = new IndexBuffer(device, indexFormat, indices.length, BUFFER_STATIC, indices);
752-
mesh.indexBuffer[0] = indexBuffer;
753-
mesh.primitive[0].count = indices.length;
754-
} else {
755-
mesh.primitive[0].count = vertexBuffer.numVertices;
756-
}
757-
758-
mesh.materialIndex = primitive.material;
759-
760-
var accessor = accessors[primitive.attributes.POSITION];
761-
var min = accessor.min;
762-
var max = accessor.max;
763-
var aabb = new BoundingBox(
764-
new Vec3((max[0] + min[0]) / 2, (max[1] + min[1]) / 2, (max[2] + min[2]) / 2),
765-
new Vec3((max[0] - min[0]) / 2, (max[1] - min[1]) / 2, (max[2] - min[2]) / 2)
766-
);
767-
mesh.aabb = aabb;
768-
769-
// morph targets
770-
if (canUseMorph && primitive.hasOwnProperty('targets')) {
771-
var targets = [];
772-
773-
primitive.targets.forEach(function (target, index) {
774-
var options = {};
775-
776-
if (target.hasOwnProperty('POSITION')) {
777-
accessor = accessors[target.POSITION];
778-
options.deltaPositions = getAccessorData(accessor, bufferViews);
779-
options.deltaPositionsType = getComponentType(accessor.componentType);
780-
if (accessor.hasOwnProperty('min') && accessor.hasOwnProperty('max')) {
781-
options.aabb = new BoundingBox();
782-
options.aabb.setMinMax(new Vec3(accessor.min), new Vec3(accessor.max));
764+
mesh.materialIndex = primitive.material;
765+
766+
var accessor = accessors[primitive.attributes.POSITION];
767+
var min = accessor.min;
768+
var max = accessor.max;
769+
var aabb = new BoundingBox(
770+
new Vec3((max[0] + min[0]) / 2, (max[1] + min[1]) / 2, (max[2] + min[2]) / 2),
771+
new Vec3((max[0] - min[0]) / 2, (max[1] - min[1]) / 2, (max[2] - min[2]) / 2)
772+
);
773+
mesh.aabb = aabb;
774+
775+
// morph targets
776+
if (canUseMorph && primitive.hasOwnProperty('targets')) {
777+
var targets = [];
778+
779+
primitive.targets.forEach(function (target, index) {
780+
var options = {};
781+
782+
if (target.hasOwnProperty('POSITION')) {
783+
accessor = accessors[target.POSITION];
784+
options.deltaPositions = getAccessorData(accessor, bufferViews);
785+
options.deltaPositionsType = getComponentType(accessor.componentType);
786+
if (accessor.hasOwnProperty('min') && accessor.hasOwnProperty('max')) {
787+
options.aabb = new BoundingBox();
788+
options.aabb.setMinMax(new Vec3(accessor.min), new Vec3(accessor.max));
789+
}
783790
}
784-
}
785791

786-
if (target.hasOwnProperty('NORMAL')) {
787-
accessor = accessors[target.NORMAL];
788-
options.deltaNormals = getAccessorData(accessor, bufferViews);
789-
options.deltaNormalsType = getComponentType(accessor.componentType);
790-
}
792+
if (target.hasOwnProperty('NORMAL')) {
793+
accessor = accessors[target.NORMAL];
794+
options.deltaNormals = getAccessorData(accessor, bufferViews);
795+
options.deltaNormalsType = getComponentType(accessor.componentType);
796+
}
791797

792-
if (gltfMesh.hasOwnProperty('extras') &&
793-
gltfMesh.extras.hasOwnProperty('targetNames')) {
794-
options.name = gltfMesh.extras.targetNames[index];
795-
} else {
796-
options.name = targets.length.toString(10);
797-
}
798+
if (gltfMesh.hasOwnProperty('extras') &&
799+
gltfMesh.extras.hasOwnProperty('targetNames')) {
800+
options.name = gltfMesh.extras.targetNames[index];
801+
} else {
802+
options.name = targets.length.toString(10);
803+
}
798804

799-
targets.push(new MorphTarget(options));
800-
});
805+
targets.push(new MorphTarget(options));
806+
});
801807

802-
mesh.morph = new Morph(targets, device);
808+
mesh.morph = new Morph(targets, device);
803809

804-
// set default morph target weights if they're specified
805-
if (gltfMesh.hasOwnProperty('weights')) {
806-
for (var i = 0; i < gltfMesh.weights.length; ++i) {
807-
targets[i].defaultWeight = gltfMesh.weights[i];
810+
// set default morph target weights if they're specified
811+
if (gltfMesh.hasOwnProperty('weights')) {
812+
for (var i = 0; i < gltfMesh.weights.length; ++i) {
813+
targets[i].defaultWeight = gltfMesh.weights[i];
814+
}
808815
}
809816
}
810817
}
@@ -2104,7 +2111,10 @@ class GlbParser {
21042111
if (gltfNode.hasOwnProperty('mesh')) {
21052112
var meshGroup = glb.meshes[gltfNode.mesh];
21062113
for (var mi = 0; mi < meshGroup.length; mi++) {
2107-
createMeshInstance(model, meshGroup[mi], glb.skins, skinInstances, glb.materials, node, gltfNode);
2114+
const mesh = meshGroup[mi];
2115+
if (mesh) {
2116+
createMeshInstance(model, mesh, glb.skins, skinInstances, glb.materials, node, gltfNode);
2117+
}
21082118
}
21092119
}
21102120
}

0 commit comments

Comments
 (0)