Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Point Cloud Update #121

Merged
merged 4 commits into from
Jul 16, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 127 additions & 0 deletions src/pointcloud/Particles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/**
* @author David V. Lu!! - [email protected]
*/

/**
* A set of particles. Used by PointCloud2.
*
* @constructor
* @param options - object with following keys:
*
* * tfClient - the TF client handle to use
* * texture - (optional) Image url for a texture to use for the points. Defaults to a single white pixel.
* * rootObject (optional) - the root object to add this marker to
* * size (optional) - size to draw each point (default 0.05)
* * max_pts (optional) - number of points to draw (default 100)
*/
ROS3D.Particles = function(options) {
options = options || {};
this.tfClient = options.tfClient;
var texture = options.texture || 'https://upload.wikimedia.org/wikipedia/commons/a/a2/Pixel-white.png';
var size = options.size || 0.05;
this.max_pts = options.max_pts || 100;
this.first_size = null;
this.prev_pts = 0;
this.rootObject = options.rootObject || new THREE.Object3D();
var that = this;
THREE.Object3D.call(this);

this.vertex_shader = [
'attribute vec3 customColor;',
'attribute float alpha;',
'varying vec3 vColor;',
'varying float falpha;',
'void main() ',
'{',
' vColor = customColor; // set color associated to vertex; use later in fragment shader',
' vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );',
' falpha = alpha; ',
'',
' // option (1): draw particles at constant size on screen',
' // gl_PointSize = size;',
' // option (2): scale particles as objects in 3D space',
' gl_PointSize = ', size, '* ( 300.0 / length( mvPosition.xyz ) );',
' gl_Position = projectionMatrix * mvPosition;',
'}'
].join('\n');

this.fragment_shader = [
'uniform sampler2D texture;',
'varying vec3 vColor; // colors associated to vertices; assigned by vertex shader',
'varying float falpha;',
'void main() ',
'{',
' // calculates a color for the particle',
' gl_FragColor = vec4( vColor, falpha );',
' // sets particle texture to desired color',
' gl_FragColor = gl_FragColor * texture2D( texture, gl_PointCoord );',
'}'
].join('\n');

this.geom = new THREE.Geometry();
for(var i=0;i<this.max_pts;i++){
this.geom.vertices.push(new THREE.Vector3( ));
}

var customUniforms =
{
texture: { type: 't', value: THREE.ImageUtils.loadTexture( texture ) },
};

this.attribs =
{
customColor: { type: 'c', value: [] },
alpha: { type: 'f', value: [] }
};

this.shaderMaterial = new THREE.ShaderMaterial(
{
uniforms: customUniforms,
attributes: this.attribs,
vertexShader: this.vertex_shader,
fragmentShader: this.fragment_shader,
transparent: true, alphaTest: 0.5
});

this.ps = new THREE.ParticleSystem( this.geom, this.shaderMaterial );
this.sn = null;

this.points = this.geom.vertices;
this.colors = this.attribs.customColor.value;
this.alpha = this.attribs.alpha.value;

};

function setFrame(particles, frame)
{
if(particles.sn===null){
particles.sn = new ROS3D.SceneNode({
frameID : frame,
tfClient : particles.tfClient,
object : particles.ps
});

particles.rootObject.add(particles.sn);
}
}

function finishedUpdate(particles, n)
{
if(particles.first_size === null){
particles.first_size = n;
particles.max_pts = Math.max(particles.max_pts, n);
}

for(var i=n; i<particles.prev_pts; i++){
particles.alpha[i] = 0.0;
}
particles.prev_pts = n;

particles.geom.verticesNeedUpdate = true;
particles.attribs.customColor.needsUpdate = true;
particles.attribs.alpha.needsUpdate = true;

if(n>particles.max_pts){
throw 'Attempted to draw more points than max_pts allows';
}
}
130 changes: 24 additions & 106 deletions src/pointcloud/PointCloud2.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ function decode64(x) {
* * ros - the ROSLIB.Ros connection handle
* * topic - the marker topic to listen to
* * tfClient - the TF client handle to use
* * texture - (optional) Image url for a texture to use for the points. Defaults to a single white pixel.
* * rootObject (optional) - the root object to add this marker to
* * size (optional) - size to draw each point (default 0.05)
* * max_pts (optional) - number of points to draw (default 100)
Expand All @@ -58,117 +59,34 @@ ROS3D.PointCloud2 = function(options) {
options = options || {};
var ros = options.ros;
var topic = options.topic || '/points';
this.tfClient = options.tfClient;
var size = options.size || 0.05;
var max_pts = options.max_pts || 100;
this.prev_pts = 0;
this.rootObject = options.rootObject || new THREE.Object3D();
var that = this;
THREE.Object3D.call(this);

this.vertex_shader = [
'attribute vec3 customColor;',
'attribute float alpha;',
'varying vec3 vColor;',
'varying float falpha;',
'void main() ',
'{',
' vColor = customColor; // set color associated to vertex; use later in fragment shader',
' vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );',
' falpha = alpha; ',
'',
' // option (1): draw particles at constant size on screen',
' // gl_PointSize = size;',
' // option (2): scale particles as objects in 3D space',
' gl_PointSize = ', size, '* ( 300.0 / length( mvPosition.xyz ) );',
' gl_Position = projectionMatrix * mvPosition;',
'}'
].join('\n');
this.particles = new ROS3D.Particles(options);

this.fragment_shader = [
'uniform sampler2D texture;',
'varying vec3 vColor; // colors associated to vertices; assigned by vertex shader',
'varying float falpha;',
'void main() ',
'{',
' // calculates a color for the particle',
' gl_FragColor = vec4( vColor, falpha );',
' // sets particle texture to desired color',
' gl_FragColor = gl_FragColor * texture2D( texture, gl_PointCoord );',
'}'
].join('\n');
var rosTopic = new ROSLIB.Topic({
ros : ros,
name : topic,
messageType : 'sensor_msgs/PointCloud2'
});

this.geom = new THREE.Geometry();
for(var i=0;i<max_pts;i++){
this.geom.vertices.push(new THREE.Vector3( ));
}

var customUniforms =
{
texture: { type: 't', value: THREE.ImageUtils.loadTexture( 'pixel.png' ) },
};

this.attribs =
{
customColor: { type: 'c', value: [] },
alpha: { type: 'f', value: [] }
};

this.shaderMaterial = new THREE.ShaderMaterial(
{
uniforms: customUniforms,
attributes: this.attribs,
vertexShader: this.vertex_shader,
fragmentShader: this.fragment_shader,
transparent: true, alphaTest: 0.5
});

this.ps = new THREE.ParticleSystem( this.geom, this.shaderMaterial );
this.sn = null;

var rosTopic = new ROSLIB.Topic({
ros : ros,
name : topic,
messageType : 'sensor_msgs/PointCloud2'
});

rosTopic.subscribe(function(message) {
rosTopic.unsubscribe();

if(that.sn===null){
that.sn = new ROS3D.SceneNode({
frameID : message.header.frame_id,
tfClient : that.tfClient,
object : that.ps
});

that.rootObject.add(that.sn);
}

var n = message.height*message.width;

var buffer;
if(message.data.buffer){
buffer = message.data.buffer;
}else{
buffer = decode64(message.data);
}
for(var i=0;i<n;i++){
var pt = read_point(message, i, buffer);
that.geom.vertices[i] = new THREE.Vector3( pt['x'], pt['y'], pt['z'] );
that.attribs.customColor.value[ i ] = new THREE.Color( pt['rgb'] );
that.attribs.alpha.value[i] = 1.0;
}
for(i=n; i<that.prev_pts; i++){
that.attribs.alpha.value[i] = 0.0;
}
that.prev_pts = n;

that.geom.verticesNeedUpdate = true;
that.attribs.customColor.needsUpdate = true;
that.attribs.alpha.needsUpdate = true;
});
rosTopic.subscribe(function(message) {
setFrame(that.particles, message.header.frame_id);

var n = message.height*message.width;
var buffer;
if(message.data.buffer){
buffer = message.data.buffer;
}else{
buffer = decode64(message.data);
}
for(var i=0;i<n;i++){
var pt = read_point(message, i, buffer);
that.particles.points[i] = new THREE.Vector3( pt['x'], pt['y'], pt['z'] );
that.particles.colors[ i ] = new THREE.Color( pt['rgb'] );
that.particles.alpha[i] = 1.0;
}

finishedUpdate(that.particles, n);
});
};
ROS3D.PointCloud2.prototype.__proto__ = THREE.Object3D.prototype;