Socket
Socket
Sign inDemoInstall

urdf-loader

Package Overview
Dependencies
Maintainers
1
Versions
53
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

urdf-loader - npm Package Compare versions

Comparing version 0.3.5 to 0.4.0

17

CHANGELOG.md

@@ -7,2 +7,19 @@ # Changelog

## Unreleased
### Changed
- Add "path" variable to parse function signature
- URDF paths are no longer resolved relative to the package path
- `parse` function signature changed
- `parse` returns the robot now
- `meshLoadCb` and `fetchOptions` have been moved into an `options` argument object
- Moved all fields from `Object3D.urdf` to the object itself
- Changed `type` to `jointType`
### Added
- Add `isURDFRobot`, `isURDFJoint`, `isURDFLink` fields to the robot, joints, and links
- Set the `type` field of the `Object3D` to `URDFRobot`, `URDFJoint`, and `URDFLink`
### Removed
- `node` field from the urdf info on joints, links, and the robot
## [0.3.5] - 2018-08-07

@@ -9,0 +26,0 @@ ### Added

81

example/index.js

@@ -1,2 +0,2 @@

/* globals animToggle viewer THREE */
/* globals viewer THREE */

@@ -7,3 +7,2 @@ // declare these globally for the sake of the example.

viewer = document.querySelector('urdf-viewer');
animToggle = document.getElementById('do-animate');

@@ -15,3 +14,3 @@ const limitsToggle = document.getElementById('ignore-joint-limits');

const controlsToggle = document.getElementById('toggle-controls');
const DEG2RAD = Math.PI / 180;
var DEG2RAD = Math.PI / 180;
const RAD2DEG = 1 / DEG2RAD;

@@ -28,48 +27,4 @@ let sliders = {};

// Functions
const lerp = (from, to, ratio) => from + (to - from) * ratio;
const updateAngles = () => {
if (!viewer.setAngle) return;
// reset everything to 0 first
const resetangles = viewer.angles;
for (const name in resetangles) resetangles[name] = 0;
viewer.setAngles(resetangles);
// animate the legs
const time = Date.now() / 3e2;
for (let i = 1; i <= 6; i++) {
const offset = i * Math.PI / 3;
const ratio = Math.max(0, Math.sin(time + offset));
viewer.setAngle(`HP${ i }`, lerp(30, 0, ratio) * DEG2RAD);
viewer.setAngle(`KP${ i }`, lerp(90, 150, ratio) * DEG2RAD);
viewer.setAngle(`AP${ i }`, lerp(-30, -60, ratio) * DEG2RAD);
viewer.setAngle(`TC${ i }A`, lerp(0, 0.065, ratio));
viewer.setAngle(`TC${ i }B`, lerp(0, 0.065, ratio));
viewer.setAngle(`W${ i }`, window.performance.now() * 0.001);
}
};
const updateLoop = () => {
if (animToggle.classList.contains('checked')) {
updateAngles();
}
requestAnimationFrame(updateLoop);
};
// Events
// toggle checkbox
animToggle.addEventListener('click', () => animToggle.classList.toggle('checked'));
limitsToggle.addEventListener('click', () => {

@@ -124,4 +79,2 @@ limitsToggle.classList.toggle('checked');

// stop the animation if user tried to manipulate the model
animToggle.classList.remove('checked');
const j = document.querySelector(`li[joint-name="${ e.detail }"]`);

@@ -140,3 +93,3 @@ if (j) {

Object
.keys(r.urdf.joints)
.keys(r.joints)
.sort((a, b) => {

@@ -157,3 +110,3 @@

})
.map(key => r.urdf.joints[key])
.map(key => r.joints[key])
.forEach(joint => {

@@ -164,8 +117,8 @@

`
<span title="${ joint.urdf.name }">${ joint.urdf.name }</span>
<span title="${ joint.name }">${ joint.name }</span>
<input type="range" value="0" step="0.0001"/>
<input type="number" step="0.0001" />
`;
li.setAttribute('joint-type', joint.urdf.type);
li.setAttribute('joint-name', joint.urdf.name);
li.setAttribute('joint-type', joint.jointType);
li.setAttribute('joint-name', joint.name);

@@ -178,5 +131,5 @@ sliderList.appendChild(li);

li.update = () => {
let degVal = joint.urdf.angle;
let degVal = joint.angle;
if (joint.urdf.type === 'revolute' || joint.urdf.type === 'continuous') {
if (joint.jointType === 'revolute' || joint.jointType === 'continuous') {
degVal *= RAD2DEG;

@@ -194,5 +147,5 @@ }

// directly input the value
slider.value = joint.urdf.angle;
slider.value = joint.angle;
if (viewer.ignoreLimits || joint.urdf.type === 'continuous') {
if (viewer.ignoreLimits || joint.jointType === 'continuous') {
slider.min = -6.28;

@@ -204,11 +157,11 @@ slider.max = 6.28;

} else {
slider.min = joint.urdf.limit.lower;
slider.max = joint.urdf.limit.upper;
slider.min = joint.limit.lower;
slider.max = joint.limit.upper;
input.min = joint.urdf.limit.lower * RAD2DEG;
input.max = joint.urdf.limit.upper * RAD2DEG;
input.min = joint.limit.lower * RAD2DEG;
input.max = joint.limit.upper * RAD2DEG;
}
};
switch (joint.urdf.type) {
switch (joint.jointType) {

@@ -251,3 +204,2 @@ case 'continuous':

viewer.addEventListener('urdf-processed', e => updateAngles());
document.querySelector('li[urdf]').dispatchEvent(new Event('click'));

@@ -259,3 +211,2 @@

updateLoop();
});
{
"name": "urdf-loader",
"version": "0.3.5",
"version": "0.4.0",
"description": "URDF Loader for THREE.js and webcomponent viewer",
"scripts": {
"start": "cd .. && static-server",
"build": "cd example && webpack"
"build": "cd example && webpack",
"test": "jest",
"lint": "eslint *.js ./test/*.js",
"coverage": "nyc report --reporter=html & opn coverage/index.html"
},
"files": [
"URDFLoader.js",
"urdf-viewer-element.js",
"urdf-manipulator-element.js",
"example/index.js",
"example/dragAndDrop.js"
],
"license": "Apache-2.0",

@@ -32,2 +42,9 @@ "repository": {

"@webcomponents/webcomponentsjs": "^2.0.0",
"eslint": "^5.3.0",
"jest": "^23.5.0",
"jest-cli": "^23.5.0",
"nyc": "^12.0.2",
"opn-cli": "^3.1.0",
"puppeteer": "^1.7.0",
"puppeteer-to-istanbul": "^1.2.2",
"script-loader": "^0.7.0",

@@ -34,0 +51,0 @@ "static-server": "^3.0.0",

@@ -1,3 +0,13 @@

# javascript urdf-loader [![npm version](https://badge.fury.io/js/urdf-loader.svg)](https://www.npmjs.com/package/urdf-loader)
# javascript urdf-loader
[
![npm version](https://img.shields.io/npm/v/urdf-loader.svg?style=flat-square)
](https://www.npmjs.com/package/urdf-loader)
[
![travis build](https://img.shields.io/travis/gkjohnson/urdf-loaders.svg?style=flat-square)
](https://travis-ci.org/gkjohnson/urdf-loaders)
[
![lgtm code quality](https://img.shields.io/lgtm/grade/javascript/g/gkjohnson/urdf-loaders.svg?style=flat-square&label=code-quality)
](https://lgtm.com/projects/g/gkjohnson/urdf-loaders/)
Utilities for loading URDF files into THREE.js and a Web Component that loads and renders the model.

@@ -9,3 +19,3 @@

## URDFLoader
## Use
```html

@@ -29,22 +39,30 @@ <script src=".../URDFLoader.js"></script>

### API
#### URDFLoader(manager)
## URDFLoader API
### constructor(manager)
Constructor
##### manager
#### manager : THREE.LoadingManager
THREE.LoadingManager. Used for transforming load URLs.
#### URDFLoader.load(package, urdfpath, robotsCallback, geometryLoader, fetchOptions)
### load(urdfpath, packages, onComplete, options)
Loads and builds the specified URDF robot in THREE.js
##### package
#### urdfpath : String
_required_
The path to the URDF file relative to the specified package directory.
#### packages : String | Object
_required_
The path representing the `package://` directory(s) to load `package://` relative files.
If the argument is a string, then it is used to replace the `package://` prefix when loading geometry. To specify multiple packages an object syntax used defining the package name to the package path:
If the argument is a string, then it is used to replace the `package://` prefix when loading geometry.
To specify multiple packages an object syntax is used defining the package name to the package path:
```js

@@ -58,30 +76,116 @@ {

##### urdf
#### onComplete(robot) : Function
_required_
The path to the URDF file relative to the specified package directory.
Callback that is called once the urdf robots have been loaded. The loaded robot is passed to the function.
##### robotCallback(robot)
See `URDFRobot` documentation.
#### options : Object
_optional_
##### options.loadMeshCallback(pathToModel, fileExtension, onComplete) : Function
An optional function that can be used to override the default mesh loading functionality. The default loader is specified at `URDFLoader.defaultMeshLoader`. `onComplete` is called with the mesh once the geometry has been loaded.
##### options.fetchOptions : Object
An optional object with the set of options to pass to the `fetch` function call used to load the URDF file.
##### workingPath : String
The path to load geometry relative to.
Defaults to the path relative to the loaded URDF file.
### parse(urdfContent, packages, onComplete, options) : THREE.Object3D
Parses URDF content and returns the robot model.
#### urdfContent : String
_required_
Callback that is called once the urdf robots have been loaded. The loaded robot is passed to the function.
The xml content of a URDF file.
The available joints are specified on `robot.urdf.joints`.
#### packages : String | Object
To set a joint angle, call `robot.urdf.joint.setAngle(angle)`.
_required_
##### geometryLoader(pathToModel, fileExtension, doneCallback)
See `load`.
#### onComplete(robot) : Function
_optional_
An optional function that can be used to override the default mesh loading functionality. The default loader is specified at `URDFLoader.defaultMeshLoader`. `doneCallback` is called with the mesh once the geometry has been loaded.
Called immediately with the generated robot. This is the same object that is returned from the function.
##### fetchOptions
Note that the link geometry will not necessarily have finished being processed when this is called.
_optional_
See `URDFRobot` documentation.
An optional object with the set of options to pass to the `fetch` function call used to load the URDF file.
#### options : Object
See `load`.
## URDFRobot
Object that describes the URDF Robot. An extension of `THREE.Object3D`.
### name : String
The name of the robot described in the `<robot>` tag.
### links : Object
A dictionary of `linkName : URDFLink` with all links in the robot.
### joints : Object
A dictionary of `jointName : URDFJoint` with all joints in the robot.
## URDFJoint
An object representing a robot joint. An extension of `THREE.Object3D`.
### name : String
The name of the joint.
### jointType : String
The type of joint. Can only be the URDF types of joints.
### limit : Object
An object containing the `lower` and `upper` constraints for the joint.
### axis : THREE.Vector3
The axis described for the joint.
### angle : Number
_readonly_
The current position or angle for joint.
### ignoreLimits : Boolean
Whether or not to ignore the joint limits when setting a the joint position.
### setAngle(angle) | setOffset(position)
#### angle | position : Number
The position off of the starting position to rotate or move the joint to.
### URDFLink
#### name
The name of the link.
## urdf-viewer Element

@@ -129,4 +233,2 @@ ```html

#### urdf

@@ -133,0 +235,0 @@

@@ -79,3 +79,3 @@ /* globals URDFViewer THREE */

return j.urdf && j.urdf.type && j.urdf.type !== 'fixed';
return j.isURDFJoint && j.jointType !== 'fixed';

@@ -153,3 +153,3 @@ };

// TODO: Why is the constant negated?
plane.normal.copy(tg.urdf.axis).transformDirection(tg.matrixWorld).normalize();
plane.normal.copy(tg.axis).transformDirection(tg.matrixWorld).normalize();
plane.constant = -plane.normal.dot(clickPoint);

@@ -230,3 +230,3 @@

plane.normal.copy(tg.urdf.axis).transformDirection(tg.parent.matrixWorld).normalize();
plane.normal.copy(tg.axis).transformDirection(tg.parent.matrixWorld).normalize();

@@ -254,3 +254,3 @@ return temp.length() * -Math.sign(temp.dot(plane.normal));

clickPoint.copy(target.point);
this.dispatchEvent(new CustomEvent('manipulate-start', { bubbles: true, cancelable: true, detail: dragging.urdf.name }));
this.dispatchEvent(new CustomEvent('manipulate-start', { bubbles: true, cancelable: true, detail: dragging.name }));
this.controls.enabled = false;

@@ -300,3 +300,3 @@

highlightLinkGeometry(wasHovered, true);
this.dispatchEvent(new CustomEvent('joint-mouseout', { bubbles: true, cancelable: true, detail: wasHovered.urdf.name }));
this.dispatchEvent(new CustomEvent('joint-mouseout', { bubbles: true, cancelable: true, detail: wasHovered.name }));

@@ -308,3 +308,3 @@ }

highlightLinkGeometry(hovered, false);
this.dispatchEvent(new CustomEvent('joint-mouseover', { bubbles: true, cancelable: true, detail: hovered.urdf.name }));
this.dispatchEvent(new CustomEvent('joint-mouseover', { bubbles: true, cancelable: true, detail: hovered.name }));

@@ -321,7 +321,7 @@ }

let delta = null;
if (dragging.urdf.type === 'revolute' || dragging.urdf.type === 'continuous') {
if (dragging.jointType === 'revolute' || dragging.jointType === 'continuous') {
delta = getAngle(dragging, mouse, lastMouse);
} else if (dragging.urdf.type === 'prismatic') {
} else if (dragging.jointType === 'prismatic') {

@@ -338,3 +338,3 @@ delta = getMove(dragging, mouse, lastMouse);

this.setAngle(dragging.urdf.name, dragging.urdf.angle + delta);
this.setAngle(dragging.name, dragging.angle + delta);

@@ -354,3 +354,3 @@ }

this.dispatchEvent(new CustomEvent('manipulate-end', { bubbles: true, cancelable: true, detail: dragging.urdf.name }));
this.dispatchEvent(new CustomEvent('manipulate-end', { bubbles: true, cancelable: true, detail: dragging.name }));
dragging = null;

@@ -357,0 +357,0 @@ this.controls.enabled = true;

@@ -50,3 +50,3 @@ /* globals THREE URDFLoader */

for (const name in this.robot.urdf.joints) angles[name] = this.robot.urdf.joints[name].urdf.angle;
for (const name in this.robot.joints) angles[name] = this.robot.joints[name].angle;

@@ -84,3 +84,2 @@ }

dirLight.shadow.mapSize.height = 2048;
dirLight.shadow.bias = -0.000025;
dirLight.castShadow = true;

@@ -95,2 +94,3 @@ scene.add(dirLight);

renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.gammaOutput = true;

@@ -137,2 +137,4 @@

this._setUp(this.up);
// redraw when something new has loaded

@@ -284,6 +286,6 @@ this.loadingManager.onLoad = () => this._dirty = true;

const joint = this.robot.urdf.joints[jointname];
if (joint && joint.urdf.angle !== angle) {
const joint = this.robot.joints[jointname];
if (joint && joint.angle !== angle) {
joint.urdf.setAngle(angle);
joint.setAngle(angle);
this._dirty = true;

@@ -436,6 +438,8 @@

pkg = pkg.split(',').reduce(function(map, value) {
pkg = pkg.split(',').reduce((map, value) => {
const [pkgName, pkgPath] = value.split(/:(.+)/).filter(x => !!x);
map[pkgName.trim()] = pkgPath.trim();
const split = value.split(/:/).filter(x => !!x);
const pkgName = split.shift().trim();
const pkgPath = split.join(':').trim();
map[pkgName] = pkgPath;

@@ -448,4 +452,4 @@ return map;

this.urdfLoader.load(
urdf,
pkg,
urdf,

@@ -477,26 +481,31 @@ // Callback with array of robots

// Load meshes and enable shadow casting
(path, ext, done) => {
// options
{
loadMeshCb: (path, ext, done) => {
totalMeshes++;
this.urdfLoader.defaultMeshLoader(path, ext, mesh => {
// Load meshes and enable shadow casting
totalMeshes++;
this.urdfLoader.defaultMeshLoader(path, ext, mesh => {
updateMaterials(mesh);
updateMaterials(mesh);
done(mesh);
done(mesh);
meshesLoaded++;
if (meshesLoaded === totalMeshes && this._requestId === requestId) {
meshesLoaded++;
if (meshesLoaded === totalMeshes && this._requestId === requestId) {
this.dispatchEvent(new CustomEvent('geometry-loaded', { bubbles: true, cancelable: true, composed: true }));
this.dispatchEvent(new CustomEvent('geometry-loaded', { bubbles: true, cancelable: true, composed: true }));
}
}
this._dirty = true;
this._dirty = true;
});
});
},
{ mode: 'cors', credentials: 'same-origin' });
},
fetchOptions: { mode: 'cors', credentials: 'same-origin' },
});
}

@@ -530,7 +539,7 @@

Object
.values(this.robot.urdf.joints)
.values(this.robot.joints)
.forEach(joint => {
joint.urdf.ignoreLimits = ignore;
joint.urdf.setAngle(joint.urdf.angle);
joint.ignoreLimits = ignore;
joint.setAngle(joint.angle);

@@ -537,0 +546,0 @@ });

@@ -90,33 +90,39 @@ /* globals THREE */

/* Public API */
// pkg: The equivelant of a (list of) ROS package(s):// directory
// urdf: The path to the URDF within the package OR absolute
// cb: Callback that is passed the model once loaded
load(pkg, urdf, cb, loadMeshCb, fetchOptions) {
// packages: The equivelant of a (list of) ROS package(s):// directory
// onComplete: Callback that is passed the model once loaded
load(urdf, packages, onComplete, options) {
// Check if a full URI is specified before
// prepending the package info
const workingPath = THREE.LoaderUtils.extractUrlBase(urdf);
const urdfPath = this.manager.resolveURL(urdf);
let path = urdf;
options = Object.assign({ workingPath }, options);
// If path is relative
if (!/^[^:]+:\/\//.test(path)) {
fetch(urdfPath, options.fetchOptions)
.then(res => res.text())
.then(data => this.parse(data, packages, onComplete, options));
// make sure we don't insert a double slash by cleaning
// the package and urdf paths
path = `${ pkg.replace(/(\\|\/)$/, '') }/${ urdf.replace(/^(\\|\/)/, '') }`;
}
}
parse(content, packages, onComplete, options) {
path = this.manager.resolveURL(path);
options = Object.assign({
fetch(path, fetchOptions)
.then(res => res.text())
.then(data => this.parse(pkg, data, cb, loadMeshCb));
loadMeshCb: this.defaultMeshLoader.bind(this),
workingPath: '',
}
}, options);
parse(pkg, content, cb, loadMeshCb) {
const result = this._processUrdf(content, packages, options.workingPath, options.loadMeshCb);
cb(this._processUrdf(pkg, content, loadMeshCb || this.defaultMeshLoader.bind(this)));
if (typeof onComplete === 'function') {
onComplete(result);
}
return result;
}

@@ -143,3 +149,3 @@

console.warn(`Could note load model at ${ path }:\nNo loader available`);
console.warn(`URDFLoader: Could not load model at ${ path }.\nNo loader available`);

@@ -153,6 +159,10 @@ }

// Resolves the path of mesh files
_resolveMeshPath(pkg, meshPath) {
_resolvePackagePath(pkg, meshPath, currPath) {
if (!/^package:\/\//.test(meshPath)) return meshPath;
if (!/^package:\/\//.test(meshPath)) {
return currPath !== undefined ? currPath + meshPath : meshPath;
}
// Remove "package://" keyword and split meshPath at the first slash

@@ -162,18 +172,19 @@ const [targetPkg, relPath] = meshPath.replace(/^package:\/\//, '').split(/\/(.+)/);

if (typeof pkg === 'string') {
// "pkg" is one single package
if (pkg.endsWith(targetPkg)) {
if (pkg.endsWith(targetPkg)) {
// "pkg" is the target package
return pkg + '/' + relPath;
} else {
// Assume "pkg" is the target package's parent directory
return pkg + '/' + targetPkg + '/' + relPath;
return pkg + '/' + targetPkg + '/' + relPath;
}
} else if (typeof pkg === 'object') {
// "pkg" is a map of packages
if (targetPkg in pkg) {

@@ -185,3 +196,4 @@

console.warn(`Error: ${ targetPkg } not found in provided pkgs!`);
console.error(`URDFLoader : ${ targetPkg } not found in provided package list!`);
return null;

@@ -193,3 +205,3 @@ }

// Process the URDF text format
_processUrdf(pkg, data, loadMeshCb) {
_processUrdf(data, packages, path, loadMeshCb) {

@@ -200,3 +212,3 @@ const parser = new DOMParser();

const robottag = this.filter(urdf.children, c => c.nodeName === 'robot').pop();
return this._processRobot(pkg, robottag, loadMeshCb);
return this._processRobot(robottag, packages, path, loadMeshCb);

@@ -206,3 +218,3 @@ }

// Process the <robot> node
_processRobot(pkg, robot, loadMeshCb) {
_processRobot(robot, packages, path, loadMeshCb) {

@@ -213,3 +225,2 @@ const links = [];

obj.name = robot.getAttribute('name');
obj.urdf = { node: robot };

@@ -230,3 +241,3 @@ // Process the <joint> and <link> nodes

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

@@ -254,4 +265,6 @@ });

obj.urdf.joints = jointMap;
obj.urdf.links = linkMap;
obj.joints = jointMap;
obj.links = linkMap;
obj.isURDFRobot = true;
obj.type = 'URDFRobot';

@@ -267,14 +280,25 @@ return obj;

const obj = new THREE.Object3D();
obj.isURDFJoint = true;
obj.type = 'URDFJoint';
obj.name = joint.getAttribute('name');
obj.urdf = {
node: joint,
name: joint.getAttribute('name'),
type: jointType,
angle: 0,
axis: null,
limit: { lower: 0, upper: 0 },
ignoreLimits: false,
setAngle: () => {},
};
obj.jointType = jointType;
obj.axis = null;
obj.angle = 0;
obj.limit = { lower: 0, upper: 0 };
obj.ignoreLimits = false;
obj.setOffset = () => {};
// copy the 'setOffset' function over to 'setAngle' so
// it makes sense for other joint types (prismatic, planar)
// TODO: Remove the 'setOffset' function
// TODO: Figure out how to handle setting and getting angles of other types
Object.defineProperties(
obj,
{
setAngle: { get() { return this.setOffset; } },
});
let parent = null;

@@ -304,4 +328,4 @@ let child = null;

obj.urdf.limit.lower = parseFloat(n.getAttribute('lower') || obj.urdf.limit.lower);
obj.urdf.limit.upper = parseFloat(n.getAttribute('upper') || obj.urdf.limit.upper);
obj.limit.lower = parseFloat(n.getAttribute('lower') || obj.limit.lower);
obj.limit.upper = parseFloat(n.getAttribute('upper') || obj.limit.upper);

@@ -326,4 +350,4 @@ }

const axisxyz = axisnode.getAttribute('xyz').split(/\s+/g).map(num => parseFloat(num));
obj.urdf.axis = new THREE.Vector3(axisxyz[0], axisxyz[1], axisxyz[2]);
obj.urdf.axis.normalize();
obj.axis = new THREE.Vector3(axisxyz[0], axisxyz[1], axisxyz[2]);
obj.axis.normalize();

@@ -336,8 +360,8 @@ }

case 'continuous':
obj.urdf.limit.lower = -Infinity;
obj.urdf.limit.upper = Infinity;
obj.limit.lower = -Infinity;
obj.limit.upper = Infinity;
// fall through to revolute joint 'setAngle' function
// fall through to revolute joint 'setOffset' function
case 'revolute':
obj.urdf.setAngle = function(angle = null) {
obj.setOffset = function(angle = null) {

@@ -365,3 +389,3 @@ if (!this.axis) return;

case 'prismatic':
obj.urdf.setAngle = function(angle = null) {
obj.setOffset = function(angle = null) {

@@ -393,8 +417,2 @@ if (!this.axis) return;

// copy the 'setAngle' function over to 'set' so
// it makes sense for other joint types (prismatic, planar)
// TODO: Remove the 'setAngle' function
// TODO: Figure out how to handle setting and getting angles of other types
obj.urdf.set = obj.urdf.setAngle;
return obj;

@@ -405,3 +423,3 @@

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

@@ -411,5 +429,6 @@ const visualNodes = this.filter(link.children, n => n.nodeName.toLowerCase() === 'visual');

obj.name = link.getAttribute('name');
obj.urdf = { node: link };
obj.isURDFLink = true;
obj.type = 'URDFLink';
this.forEach(visualNodes, vn => this._processVisualNode(pkg, vn, obj, loadMeshCb));
this.forEach(visualNodes, vn => this._processVisualNode(vn, obj, packages, path, loadMeshCb));

@@ -421,3 +440,3 @@ return obj;

// Process the visual nodes into meshes
_processVisualNode(pkg, vn, linkObj, loadMeshCb) {
_processVisualNode(vn, linkObj, packages, path, loadMeshCb) {

@@ -439,28 +458,34 @@ let xyz = [0, 0, 0];

const filename = n.children[0].getAttribute('filename');
const path = this._resolveMeshPath(pkg, filename);
const ext = path.match(/.*\.([A-Z0-9]+)$/i).pop() || '';
const scaleAttr = n.children[0].getAttribute('scale');
if (scaleAttr) scale = this._processTuple(scaleAttr);
const filePath = this._resolvePackagePath(packages, filename, path);
loadMeshCb(path, ext, obj => {
// file path is null if a package directory is not provided.
if (filePath !== null) {
if (obj) {
const ext = filePath.match(/.*\.([A-Z0-9]+)$/i).pop() || '';
const scaleAttr = n.children[0].getAttribute('scale');
if (scaleAttr) scale = this._processTuple(scaleAttr);
if (obj instanceof THREE.Mesh) {
loadMeshCb(filePath, ext, obj => {
obj.material.copy(material);
if (obj) {
}
if (obj instanceof THREE.Mesh) {
linkObj.add(obj);
obj.material.copy(material);
obj.position.set(xyz[0], xyz[1], xyz[2]);
obj.rotation.set(0, 0, 0);
obj.scale.set(scale[0], scale[1], scale[2]);
this._applyRotation(obj, rpy);
}
}
linkObj.add(obj);
});
obj.position.set(xyz[0], xyz[1], xyz[2]);
obj.rotation.set(0, 0, 0);
obj.scale.set(scale[0], scale[1], scale[2]);
this._applyRotation(obj, rpy);
}
});
}
} else if (geoType === 'box') {

@@ -533,5 +558,6 @@

const filename = c.getAttribute('filename').replace(/^(package:\/\/)/, '');
const path = pkg + '/' + filename;
material.map = this._textureloader.load(path);
const filePath = this._resolvePackagePath(packages, filename, path);
material.map = this._textureloader.load(filePath);
}

@@ -538,0 +564,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc