Skip to content

Commit

Permalink
Merge pull request #72 from rapyuta-robotics/master
Browse files Browse the repository at this point in the history
Handle materials referenced by name specified outside the link object
  • Loading branch information
gkjohnson authored Oct 31, 2018
2 parents 9924afc + b53fb19 commit aa95e24
Showing 1 changed file with 71 additions and 36 deletions.
107 changes: 71 additions & 36 deletions javascript/URDFLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,8 @@ class URDFLoader {
if (/\.stl$/i.test(path)) {

this.STLLoader.load(path, geom => {

const mesh = new THREE.Mesh();
mesh.geometry = geom;
const mesh = new THREE.Mesh(geom, new THREE.MeshPhongMaterial());
done(mesh);

});

} else if (/\.dae$/i.test(path)) {
Expand Down Expand Up @@ -213,6 +210,7 @@ class URDFLoader {
// Process the <robot> node
_processRobot(robot, packages, path, loadMeshCb) {

const materials = robot.querySelectorAll('material');
const links = [];
const joints = [];
const obj = new THREE.Object3D();
Expand All @@ -224,15 +222,31 @@ class URDFLoader {
const type = n.nodeName.toLowerCase();
if (type === 'link') links.push(n);
else if (type === 'joint') joints.push(n);
});

// Create the <material> map
const materialMap = {};
this.forEach(materials, m => {
const name = m.getAttribute('name');
if (!materialMap[name]) {
materialMap[name] = {};
this.forEach(m.children, c => {
this._processMaterial(
materialMap[name],
c,
packages,
path
);
});
}
});

// Create the <link> map
const linkMap = {};
this.forEach(links, l => {

const name = l.getAttribute('name');
linkMap[name] = this._processLink(l, packages, path, loadMeshCb);
linkMap[name] = this._processLink(l, materialMap, packages, path, loadMeshCb);

});

Expand Down Expand Up @@ -406,23 +420,52 @@ class URDFLoader {
}

// Process the <link> nodes
_processLink(link, packages, path, loadMeshCb) {
_processLink(link, materialMap, packages, path, loadMeshCb) {

const visualNodes = this.filter(link.children, n => n.nodeName.toLowerCase() === 'visual');
const obj = new THREE.Object3D();
obj.name = link.getAttribute('name');
obj.isURDFLink = true;
obj.type = 'URDFLink';

this.forEach(visualNodes, vn => this._processVisualNode(vn, obj, packages, path, loadMeshCb));
this.forEach(visualNodes, vn => this._processVisualNode(vn, obj, materialMap, packages, path, loadMeshCb));

return obj;

}

// Process the visual nodes into meshes
_processVisualNode(vn, linkObj, packages, path, loadMeshCb) {
_processMaterial(material, node, packages, path) {
const type = node.nodeName.toLowerCase();
if (type === 'color') {
const rgba = node.getAttribute('rgba').split(/\s/g)
.map(v => parseFloat(v));
this._copyMaterialAttributes(material, {
color: new THREE.Color(rgba[0], rgba[1], rgba[2]),
opacity: rgba[3],
transparent: rgba[3] < 1,
});
} else if (type === 'texture') {
const filename = node.getAttribute('filename').replace(/^(package:\/\/)/, '').replace(/^(package:\/\/)/, '');
const filePath = this._resolvePackagePath(packages, filename, path);
this._copyMaterialAttributes(material, {
map: this.TextureLoader.load(filePath),
});
}
}

_copyMaterialAttributes(material, materialAttributes) {
if ('color' in materialAttributes) {
material.color = materialAttributes.color.clone();
material.opacity = materialAttributes.opacity;
material.transparent = materialAttributes.transparent;
}
if ('map' in materialAttributes) {
material.map = materialAttributes.map.clone();
}
}

// Process the visual nodes into meshes
_processVisualNode(vn, linkObj, materialMap, packages, path, loadMeshCb) {
let xyz = [0, 0, 0];
let rpy = [0, 0, 0];
let scale = [1, 1, 1];
Expand Down Expand Up @@ -518,35 +561,27 @@ class URDFLoader {
rpy = this._processTuple(n.getAttribute('rpy'));

} else if (type === 'material') {
const materialName = n.getAttribute('name');
if (n.children.length) {
this.forEach(n.children, c => {
switch (c.nodeName.toLowerCase()) {

case 'color':
this._processMaterial(material, c);
break;
case 'texture':
if (materialName in materialMap) {
this._copyMaterialAttributes(material, materialMap[materialName]);
} else {
this._processMaterial(material, c, packages, path);
}

this.forEach(n.children, c => {

if (c.nodeName.toLowerCase() === 'color') {

const rgba = c.getAttribute('rgba')
.split(/\s/g)
.map(v => parseFloat(v));

material.color.r = rgba[0];
material.color.g = rgba[1];
material.color.b = rgba[2];
material.opacity = rgba[3];

if (material.opacity < 1) material.transparent = true;

} else if (c.nodeName.toLowerCase() === 'texture') {

const filename = c.getAttribute('filename').replace(/^(package:\/\/)/, '');
const filePath = this._resolvePackagePath(packages, filename, path);

material.map = this._textureloader.load(filePath);

}

});

}
});
} else {
this._copyMaterialAttributes(material, materialMap[materialName]);
}
}

});

// apply the position and rotation to the primitive geometry after
Expand Down

0 comments on commit aa95e24

Please sign in to comment.