mirror of
https://github.com/CesiumGS/obj2gltf.git
synced 2025-03-01 22:13:49 -05:00
Same as #161
This commit is contained in:
parent
f339c81494
commit
bab00f2558
@ -78,6 +78,7 @@ function loadObj(objPath, options) {
|
|||||||
var node;
|
var node;
|
||||||
var mesh;
|
var mesh;
|
||||||
var primitive;
|
var primitive;
|
||||||
|
var activeMaterial;
|
||||||
|
|
||||||
// All nodes seen in the obj
|
// All nodes seen in the obj
|
||||||
var nodes = [];
|
var nodes = [];
|
||||||
@ -125,6 +126,7 @@ function loadObj(objPath, options) {
|
|||||||
|
|
||||||
function addPrimitive() {
|
function addPrimitive() {
|
||||||
primitive = new Primitive();
|
primitive = new Primitive();
|
||||||
|
primitive.material = activeMaterial;
|
||||||
mesh.primitives.push(primitive);
|
mesh.primitives.push(primitive);
|
||||||
|
|
||||||
// Clear the vertex cache for each new primitive
|
// Clear the vertex cache for each new primitive
|
||||||
@ -132,22 +134,42 @@ function loadObj(objPath, options) {
|
|||||||
vertexCount = 0;
|
vertexCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function useMaterial(name) {
|
function reusePrimitive(callback) {
|
||||||
// Look to see if this material has already been used by a primitive in the mesh
|
|
||||||
var material = getName(name);
|
|
||||||
var primitives = mesh.primitives;
|
var primitives = mesh.primitives;
|
||||||
var primitivesLength = primitives.length;
|
var primitivesLength = primitives.length;
|
||||||
for (var i = 0; i < primitivesLength; ++i) {
|
for (var i = 0; i < primitivesLength; ++i) {
|
||||||
if (primitives[i].material === material) {
|
if (primitives[i].material === activeMaterial) {
|
||||||
primitive = primitives[i];
|
if (!defined(callback) || callback(primitives[i])) {
|
||||||
clearVertexCache();
|
primitive = primitives[i];
|
||||||
vertexCount = primitive.positions.length / 3;
|
clearVertexCache();
|
||||||
return;
|
vertexCount = primitive.positions.length / 3;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Add a new primitive with this material
|
|
||||||
addPrimitive();
|
addPrimitive();
|
||||||
primitive.material = getName(name);
|
}
|
||||||
|
|
||||||
|
function useMaterial(name) {
|
||||||
|
activeMaterial = getName(name);
|
||||||
|
reusePrimitive();
|
||||||
|
}
|
||||||
|
|
||||||
|
function faceAndPrimitiveMatch(uvs, normals, primitive) {
|
||||||
|
var faceHasUvs = uvs[0].length > 0;
|
||||||
|
var faceHasNormals = normals[0].length > 0;
|
||||||
|
var primitiveHasUvs = primitive.uvs.length > 0;
|
||||||
|
var primitiveHasNormals = primitive.normals.length > 0;
|
||||||
|
return primitiveHasUvs === faceHasUvs && primitiveHasNormals === faceHasNormals;
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkPrimitive(uvs, normals) {
|
||||||
|
var firstFace = primitive.indices.length === 0;
|
||||||
|
if (!firstFace && !faceAndPrimitiveMatch(uvs, normals, primitive)) {
|
||||||
|
reusePrimitive(function(primitive) {
|
||||||
|
return faceAndPrimitiveMatch(uvs, normals, primitive);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOffset(a, attributeData, components) {
|
function getOffset(a, attributeData, components) {
|
||||||
@ -269,16 +291,7 @@ function loadObj(objPath, options) {
|
|||||||
function addFace(vertices, positions, uvs, normals) {
|
function addFace(vertices, positions, uvs, normals) {
|
||||||
var i;
|
var i;
|
||||||
var isWindingCorrect;
|
var isWindingCorrect;
|
||||||
|
checkPrimitive(uvs, normals);
|
||||||
var firstFace = primitive.indices.length === 0;
|
|
||||||
var faceHasUvs = uvs[0].length > 0;
|
|
||||||
var faceHasNormals = normals[0].length > 0;
|
|
||||||
var primitiveHasUvs = primitive.uvs.length > 0;
|
|
||||||
var primitiveHasNormals = primitive.normals.length > 0;
|
|
||||||
if (!firstFace && (faceHasUvs !== primitiveHasUvs || faceHasNormals !== primitiveHasNormals)) {
|
|
||||||
// Discard faces that don't use the same attributes
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vertices.length === 3) {
|
if (vertices.length === 3) {
|
||||||
isWindingCorrect = checkWindingCorrect(positions[0], positions[1], positions[2], normals[0]);
|
isWindingCorrect = checkWindingCorrect(positions[0], positions[1], positions[2], normals[0]);
|
||||||
@ -347,10 +360,12 @@ function loadObj(objPath, options) {
|
|||||||
positions.push(position.y);
|
positions.push(position.y);
|
||||||
positions.push(position.z);
|
positions.push(position.z);
|
||||||
} else if ((result = normalPattern.exec(line) ) !== null) {
|
} else if ((result = normalPattern.exec(line) ) !== null) {
|
||||||
var normal = scratchCartesian;
|
var normal = Cartesian3.fromElements(parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3]), scratchNormal);
|
||||||
normal.x = parseFloat(result[1]);
|
if (Cartesian3.equals(normal, Cartesian3.ZERO)) {
|
||||||
normal.y = parseFloat(result[2]);
|
Cartesian3.clone(Cartesian3.UNIT_Z, normal);
|
||||||
normal.z = parseFloat(result[3]);
|
} else {
|
||||||
|
Cartesian3.normalize(normal, normal);
|
||||||
|
}
|
||||||
if (defined(axisTransform)) {
|
if (defined(axisTransform)) {
|
||||||
Matrix4.multiplyByPointAsVector(axisTransform, normal, normal);
|
Matrix4.multiplyByPointAsVector(axisTransform, normal, normal);
|
||||||
}
|
}
|
||||||
@ -375,7 +390,9 @@ function loadObj(objPath, options) {
|
|||||||
faceUvs.push(result[2]);
|
faceUvs.push(result[2]);
|
||||||
faceNormals.push(result[3]);
|
faceNormals.push(result[3]);
|
||||||
}
|
}
|
||||||
addFace(faceVertices, facePositions, faceUvs, faceNormals);
|
if (faceVertices.length > 2) {
|
||||||
|
addFace(faceVertices, facePositions, faceUvs, faceNormals);
|
||||||
|
}
|
||||||
|
|
||||||
faceVertices.length = 0;
|
faceVertices.length = 0;
|
||||||
facePositions.length = 0;
|
facePositions.length = 0;
|
||||||
@ -398,17 +415,20 @@ function loadObj(objPath, options) {
|
|||||||
uvs = undefined;
|
uvs = undefined;
|
||||||
|
|
||||||
// Load materials and images
|
// Load materials and images
|
||||||
return finishLoading(nodes, mtlPaths, objPath, options);
|
return finishLoading(nodes, mtlPaths, objPath, defined(activeMaterial), options);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function finishLoading(nodes, mtlPaths, objPath, options) {
|
function finishLoading(nodes, mtlPaths, objPath, usesMaterials, options) {
|
||||||
nodes = cleanNodes(nodes);
|
nodes = cleanNodes(nodes);
|
||||||
if (nodes.length === 0) {
|
if (nodes.length === 0) {
|
||||||
return Promise.reject(new RuntimeError(objPath + ' does not have any geometry data'));
|
return Promise.reject(new RuntimeError(objPath + ' does not have any geometry data'));
|
||||||
}
|
}
|
||||||
return loadMaterials(mtlPaths, objPath, options)
|
return loadMaterials(mtlPaths, objPath, options)
|
||||||
.then(function(materials) {
|
.then(function(materials) {
|
||||||
|
if (materials.length > 0 && !usesMaterials) {
|
||||||
|
assignDefaultMaterial(nodes, materials, usesMaterials);
|
||||||
|
}
|
||||||
var imagePaths = getImagePaths(materials);
|
var imagePaths = getImagePaths(materials);
|
||||||
return loadImages(imagePaths, objPath, options)
|
return loadImages(imagePaths, objPath, options)
|
||||||
.then(function(images) {
|
.then(function(images) {
|
||||||
@ -494,6 +514,23 @@ function getImagePaths(materials) {
|
|||||||
return Object.keys(imagePaths);
|
return Object.keys(imagePaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function assignDefaultMaterial(nodes, materials) {
|
||||||
|
var defaultMaterial = materials[0].name;
|
||||||
|
var nodesLength = nodes.length;
|
||||||
|
for (var i = 0; i < nodesLength; ++i) {
|
||||||
|
var meshes = nodes[i].meshes;
|
||||||
|
var meshesLength = meshes.length;
|
||||||
|
for (var j = 0; j < meshesLength; ++j) {
|
||||||
|
var primitives = meshes[j].primitives;
|
||||||
|
var primitivesLength = primitives.length;
|
||||||
|
for (var k = 0; k < primitivesLength; ++k) {
|
||||||
|
var primitive = primitives[k];
|
||||||
|
primitive.material = defaultValue(primitive.material, defaultMaterial);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function removeEmptyMeshes(meshes) {
|
function removeEmptyMeshes(meshes) {
|
||||||
return meshes.filter(function(mesh) {
|
return meshes.filter(function(mesh) {
|
||||||
// Remove empty primitives
|
// Remove empty primitives
|
||||||
|
@ -417,11 +417,15 @@ describe('loadObj', function() {
|
|||||||
}), done).toResolve();
|
}), done).toResolve();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('discards faces that don\'t use the same attributes as other faces in the primitive', function(done) {
|
it('separates faces that don\'t use the same attributes as other faces in the primitive', function(done) {
|
||||||
expect(loadObj(objMixedAttributesUrl, defaultOptions)
|
expect(loadObj(objMixedAttributesUrl, defaultOptions)
|
||||||
.then(function(data) {
|
.then(function(data) {
|
||||||
var primitive = getPrimitives(data)[0];
|
var primitives = getPrimitives(data);
|
||||||
expect(primitive.indices.length).toBe(18); // 3 faces removed
|
expect(primitives.length).toBe(4);
|
||||||
|
expect(primitives[0].indices.length).toBe(18); // 6 faces
|
||||||
|
expect(primitives[1].indices.length).toBe(6); // 2 faces
|
||||||
|
expect(primitives[2].indices.length).toBe(6); // 2 faces
|
||||||
|
expect(primitives[3].indices.length).toBe(6); // 2 faces
|
||||||
}), done).toResolve();
|
}), done).toResolve();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user