THREE.js translation/position weirdness - javascript

I'm trying to generate random planes that would be in random position in the screen and of random size. The problem I have is that I really don't understand the set.position values. What are they representing? I tried to search every where for an answer but couldn't find.
Here's my code for the planes:
var planes = [];
for (i = 0; i < 20; i++) {
var geometry = new THREE.PlaneGeometry(sizeWidth*((randomSO(1,20)*0.00001)), sizeHeight*((randomSO(1,10)*0.0001)));
var material = new THREE.MeshBasicMaterial( {color: 0x00ff00});
var plane = new THREE.Mesh(geometry, material);
plane.drawMode = THREE.TrianglesDrawMode;
plane.position.set(-10+i, 0, 0);
scene.add(plane);
planes[i] = plane;
}
The X-co-ordinate in above example isn't how I'd want it but is like that for testing. I would like to work according to screensize, that each plane would locate in random % of the width and height. The width of my screen is 1280 and now when I set the the x co-ordinate to let's say -20 it's already out of the screen. Should I set the Z co-ordinate of the camera differently? I really don't understand the position co-ordinates in this :-(

Related

How can I scale down a mesh in three.js

I have a mesh that I want to scale down (shrink) in three.js.
I've tried the following code with no hope:
Can anyone advise please?
drawMesh(vAngles, hAngles, intensities) {
let vLines = this.getVerticalDistribution(vAngles, hAngles, intensities);
let hLines = this.getHorizontalDistribution(vAngles, hAngles, intensities);
let mesh = new THREE.Mesh();
mesh.add(...vLines);
mesh.add(...hLines);
mesh.rotation.y = Math.PI;
mesh.scale.set(0.25,0.25, 0.25);
mesh.matrixAutoUpdate = true;
}
When I set the scale value to 0.05 the Mesh get scaled down, so I think the units used needed to match the scale ratio.

Three.js grid Axis label issue and how to plot x,y,z data on the grid

I am supposed to plot the well deviation surveys on a 3D grid. With the help of a few articles on the web, I have accomplished a 3D grid with required size. The current problem I am facing right now is that the labels for x,y and z axis are attached to the grid, rather they are misplaced on the scene.
var labelsH = labelAxis(height, data.labels.y,"y");
labelsH.position.x = width;
labelsH.position.y = - height +(2*height/a)-20;
labelsH.position.z = depth;
scene.add(labelsH);
function labelAxis(width, data, direction){
var separator = 2*width/data.length,
p = {
x:0,
y:0,
z:0
},
dobj = new THREE.Object3D();
for ( var i = 0; i < data.length; i ++ ) {
var label = makeTextSprite(data[i]);
label.position.set(p.x,p.y,p.z);
dobj.add( label );
if (direction=="y"){
p[direction]+=separator;
}else{
p[direction]-=separator;
}
//console.log(p.x+":"+p.y+":"+p.z)
}
return dobj;
}
See the https://jsfiddle.net/3tw3dt1u/ for full code example.
Further more, the data that I need to plot is already in the jsFiddle mentioned above. Having minimal javascript skills, I have no idea how this data will be plotted on the grid to form something like this:
see image for required result
Thanks a lot in advance for any help.
Your question is regarding the plotting of the points, this is how it could be done:
JSFiddle working example
The key points are below.
// Not necessary, but I prefer to use the same scale as they use in their example. It's also easier since the data is according to those scales.
var graphDimensions = {
w:3000,
d:3000,
h:7000
};
var vectors = realData.map(function(d) { // Create vectors from your data
return new THREE.Vector3(d[0], d[1], d[2]);
});
var curve = new THREE.CatmullRomCurve3(vectors); // Create a curve with the vectors created above
var material = new THREE.LineBasicMaterial({color: "blue"}); // Material for the curve
var geometry = new THREE.Geometry();
var splinePoints = curve.getPoints(5000); // The 5000 in here is the resolution (number of points) on the curve. Increase for a smoother curve, decrease for a more jagged curve.
for (var i = 0; i < splinePoints.length; i++) { // Loop through the points to create vertices in the geometry
geometry.vertices.push(splinePoints[i]);
}
var line = new THREE.Line(geometry, material); // Create a line with your geometry and material
scene.add(line); // Add it to the scene
line.rotateX(Math.PI / 2); // Orient the line correctly
boundingGrid.position.set(0, -3.5, 1.5); // Move the grid into position
boundingGrid.scale.set(0.001, 0.001, 0.001); // Reduce by whatever scale you want to decrease it in size (otherwise you have to scroll out forever)
line.scale.set(0.001, 0.001, 0.001);

How would I create a terrain like this in Three.js

I am trying to create a terrain from a heightmap with a "closed" bottom see the example here:
http://demos.playfuljs.com/terrain/
My terrain generation function is as so:
var img = document.getElementById("landscape-image");
var numSegments = img.width - 1; // We have one less vertex than pixel
var geometry = new THREE.PlaneGeometry(2400, 2400, numSegments, numSegments);
var material = new THREE.MeshLambertMaterial({
color: 0xccccff,
wireframe: false
});
plane = new THREE.Mesh(geometry, material);
plane.name = 'Terrain';
// set height of vertices
for (var i = 0; i < plane.geometry.vertices.length; i++) {
plane.geometry.vertices[i].z = (terrain[i]/255) * height;
}
geometry.computeFaceNormals();
geometry.computeVertexNormals();
plane.position.x = 0;
plane.rotation.x = 0;
plane.position.y = -10;
The problem I am having is how do I create that connected bottom part of the terrain with a THREE.PlaneGeometry. I can't extrude as:
The bottom must be flat if I extrude it will be bumpy like the
terrain.
Extrude takes a Shape object, not a Geometry object.
Really scratching my head here anyone done this before.
Edit: Maybe I could use two planes and merge them but how would I merge the side faces into a single piece of Geometery ?
P.S. The example draws straight to the canvas
create a plane for each side which has your amount of Segments in width and 1 in height. them set the top Vertices according to your heightmap
something like this
var geometry_l = new THREE.PlaneGeometry(2400, 0, numSegments, 1);
plane_l = new THREE.Mesh(geometry_l, material);
for (var i = 0; i < numSegments; i++) {
plane_l.geometry_l.vertices[i].z = (Terrain[0][i]/255) * height;
}
//Offset to the edge of your main plane
you might want to Change your Terrain Array to be two-dimensional for this. so you can always read the row you want.

Three js Raycasting intercepting particles with attenuated sizes

I'm trying to use a Raycaster to intercept particles in a PointCloud object.
The point cloud is being created as such:
... other initializations, like the scene object...
var geometry = new THREE.Geometry();
var sprite = THREE.ImageUtils.loadTexture("myAwesomeIcon");
for (i = 0; i < 100000; i++) {
var vertex = new THREE.Vector3();
vertex.x = 15000 * Math.random() - 1000;
vertex.y = 15000 * Math.random() - 1000;
vertex.z = 15000 * Math.random() - 1000;
geometry.vertices.push(vertex);
}
var material = new THREE.PointCloudMaterial({
size : 30,
sizeAttenuation : true,
map : sprite,
transparent : true
});
var particles = new THREE.PointCloud(geometry, material);
particles.sortParticles = true;
scene.add(particles);
The raycaster, in its turn, is created as such:
var raycaster = new THREE.Raycaster();
raycaster.params.PointCloud.threshold = 15;
However, given that I want the sizes of the particles to change based on the camera's proximity (sizeAttenuation : true), I need the threshold param to "adapt" to each particle.
Right now, it may detect the particle too soon (when it's closer to the camera), or too late (when it's further from the camera. By too soon/late I mean in respect to the mouse position over the particle.
I found this solution online, but it assumes that I know the sizes of each particle, which I don't. I only know the initial (non-attenuated) size.
Thank you very much.

Threejs, making glass shatter effect

I have an idea to create, but since my knowledge about Three.js and 3D programming in general is limited, I am stuck...
Idea: User is doing some things. At some point - whole front screen crashes, and reveals something different behind.
At the beginning, my idea was - make screenshot, of what is happening right now, put that image in front of everything (still, having difficulties making that plane to take 100% size - idea - when it shows, user cannot tell the difference, between old 3d renderings, and new 2d picture), and then - shatter it. So - by looking around the Web for different examples, I made some... thing - Created screenshot, made plane and applied screenshot as a texture to it. To create shattering effect, I used TessellateModifier to divide that plane, and ExplodeModifier to create each face as separated face.
Here will be the code I made so far.
function drawSS()
{
var img = new Image;
img.onload = function() { // When screenshot is ready
var canvas = document.createElement('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var context = canvas.getContext('2d');
// CANVAS DRAWINGS
// Draws screenshot
// END
var texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
var multiMaterial = [
new THREE.MeshBasicMaterial({map: texture, side: THREE.FrontSide}), // canvas drawings
new THREE.MeshBasicMaterial( { color: 0xffffff, wireframe: true, transparent: true}) // for displaying wireframe
];
var geometry = new THREE.PlaneGeometry(canvas.width, canvas.height); // create plane
for (var i = 0, len = geometry.faces.length; i < len; i++) { // Snippet from some stackoverflow post, that works.
var face = geometry.faces[i].clone();
face.materialIndex = 1;
geometry.faces.push(face);
geometry.faceVertexUvs[0].push(geometry.faceVertexUvs[0][i].slice(0));
}
geometry.dynamic = true;
THREE.GeometryUtils.center( geometry ); // ?
var tessellateModifier = new THREE.TessellateModifier( 10 );
for ( var i = 0; i < 5; i ++ )
tessellateModifier.modify( geometry );
new THREE.ExplodeModifier().modify( geometry );
geometry.vertices[0].x -=300;
geometry.vertices[1].x -=300;
geometry.vertices[2].x -=300;
var mesh = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial(multiMaterial) );
scene.add( mesh );
};
// THEN, set the src
img.src = THREEx.Screenshot.toDataURL(renderer);
}
For now - I moved 1 face, by changing coordinates of 3 vertices. I'm asking - if this approach is the way to go? Result looks like this. (white lines - wireframe, black lines - (drawings in canvas) my desired wireframes - problem for later). Note - by moving this way - texture goes along, I don't know, if I make new triangles using these vertices, how would I set texture.

Categories