threejs (r72) point cloud movement - javascript

I'm working with the most recent r72 of THREEJS, and am trying to accomplish some effects that I used to do with pointclouds, which has now been replaced with the Points object.
I've set up a codepen http://codepen.io/shomanishikawa/pen/NGaWdW - both orbs are made by creating a geometry and pushing Vector3's to them.
I'd like to have individual points in the points object move at different velocities/directions, which was previously accomplished easily by setting something like
particle.velocity.y = 20
Which now seems to have no effect.
The orb on the left uses a BufferGeometry with a ShaderMaterial
The orb on the right uses a Geometry with a PointsMaterial
How can I set velocities on individual points so I can have them orbit around the radius instead of just rotating the parent Points object?
I'd like to accomplish this with a regular Geometry if possible, since I'd like finer control of moving the vertices individually. Provided examples of both just in case it's only feasible with one version.

Related

three.js How to hack OutlinePass to outline all selected objects?

I would like to modify the OutlinePass to outline all of the selected objects in the scene, including those contained within the bounds of the other in screen space (I also hope I just used that term correctly).
I am using three.js OutlinePass to indicate objects currently selected in the scene. With ray picking I append to the selected objects array, then update outlinePass.selectedObjects with said array.
The objects I select are PlaneBufferGeometry with MeshBasicMaterial. Each next drawn plane has increasing renderOrder as well as, just slightly, larger z axis offset (which in my case points upwards), so that you can correctly pick them.
If I select two disjoint planes, the outline works correctly.
If I select two intersecting planes, the outline works okay - it only draws around the two intersecting shapes -- this effect is actually nice, but would collide with fixing the next point anyway.
If I select two planes, where one is contained within the other (contained in terms of view, looking from where the camera is), then only the outer shape is outlined. Yes, that's probably a feature of OutlinePass, not a bug.
Current outline behaviour matches what it's designed to do (linked easy to understand list of steps it does).
I've spent at least 1-2 hours following the OutlinePass source, but I'm not familiar with the subject of vertex shaders or depth masks and while I would like to learn about them in the future, I can't do that right now. I believe the OutlinePass could be modified to achieve what I need.
The OutlinePass currently overrides the scene material to prepare for the edge detection pass. I'm hoping by modifying that behavior (so different objects have different materials, hence can be detected by edge detection pass) could either be modified by changing one of the used shaders or depth parameters to distinguish different objects to outline (and not only their "encompassing shapes", so to speak).
JS fiddle here, look for the UNCOMMENT line at the bottom of JS to see the issue I described. Once you uncomment that line, I would like both of these planes to be outlined.
I'm aware there are other ways to show object outlines (like enlarging an object copy behind it), but I'm interested in using the OutlinePass :). Thank you!

Performant GL Triangles Mapbox GL JS

I am working on trying to create a basic, grid-based, but performant weather-arrow visualization system.
EDIT 2:
Up-to-date version here: ( Mapbox Tracker ) of the system using the workflow which is described below
Usage Instructions:
- Click on Wind icon (on the left)
- Wait for triangles to occupy screen
- Pan time-slider (at the bottom)
As you will observe (especially on larger resolutions or when panning time slider quickly) there is quite a performance hit when drawing the triangles.
I would greatly appreciate any advice on where to start with either using something in the current API which would help, or any ideas on how to tap into the current graphics pipeline with some type of custom buffer where I would only need to rotate, scale, change color of triangles already populated in screen space.
I feel as though my specific use-case would greatly benefit from something like this, I really just don't know how to approach it.
I have a naive implementation running using this workflow:
Create a geojson FeatureCollection source
Create a fill layer
Using Data Driven property: fill-color
Data function:
Get map bounds
Project sw & ne into screen points (map.project(LatLng))
Divide height and width into portions
Loop through width and height portions
Lookup data
Access data rotation property
Create vertices based on center point + size
Rotate vertices
Create Point objects for vertices
Unproject Point Object and wrap map.unproject(Point).wrap()
Create Feature Object, assign Data driven Color
Assign unprojected LatLng as Coordinates to Polygon geometry
Add to Feature Array for Collection
Call setData on layer
So while this works, I'm looking for advice for a more performance friendly approach.
What I'm thinking here is whether I can somehow create a custom layer, one where I only need to draw to screen co-ordinates to represent the data relative to its LatLng point. So that I can draw colored, scaled, rotated triangles in screen space, and then have them update to relevant data from the new relative LatLng position.
E.g. Update some type of Mesh on screen instead of having to: unproject, then update feature collection source using map.getSource('arrows').setData(d), requestAnimationFrame(function) etc.
I've done similar in three.js in other projects but I would much rather use something that is more mapbox native. Does this sound feasible? Am I going to see a decent performance boost if so?
I've not dealt with raw gl calls before etc so I might need a pointer or two in the right direction if its going to need to get as low level as that.
EDIT:
Previous Implementation using gmaps / three.js : volvooceanrace
(wait for button on left to go from grey to black) click on top button which shows a 'wind' label when hovered over, slide red time bar underneath to change data.
Added screenshot of current working implementation
Mapbox GL Arrows
Not sure what was available in 2016, but a reasonable approach these days might be to use symbol layers, and the icon-rotate data-driven property to rotate each icon based on the property of its data point.

Geometry from curve

I have a closed spline in 3D and wish to create a flat mesh according to this spline. The points are in 3D, but are constrained to a plane. Either a completely flat or an extruded one is ok. I understand I need to supply some kind of direction for the mesh to extend in and can provode either two splines and then I want to fill in the hole between those with triangles, or I can provide a normal direction for each point on the spline for the mesh to extend to. How would I go about this, I see there are lots of classes already in THREE.js, but I can't understand how to use these. Should I make my own, and how would I go about that?

Changing geometry/material of mesh with distance

I'm making a game with three.js in which an mesh will be rendered in greater detail as the player gets closer (i.e different geometry and material). This seems like it would be a common requirement in open world type games, and I was wondering what standard procedure is in three.js
It looks like changing the geometry of a mesh is quite computationally costly, so should I just store a different mesh for each distance, or is there an existing data structure for this purpose?
You want to use level-of-detail (LOD) modeling.
There is an example of that in the following three.js example: http://threejs.org/examples/webgl_lod.html
In the example, press the 'W/S' keys to see the effect.
three.js r.62

3D models on a Node.js server

I'm making a 3D game, and I was told here and here that I should always perform collision detection on the server-side. Now, the problem is that I don't know how! Collision between players on a flat plane are easy, because players are represented by a cylinder, but, how do I do collision detection when the map itself is a model with hills and so on? Is is possible to somehow import a 3D model on a Node.js server? And then, say I do have the model imported, are there some collision detection libraries, or will I have to do the math myself? (My last resort would be converting the models to JSON (models are already converted to JSON) and then reading in all the vertices, but that would be a pain.)
The models are made in Blender and can be converted to .obj, .dae or .js (JSON) (this is what I currently use).
If there are no such modules, that allow the models to be imported and collisions to be checked against them, I guess I could make it myself. In that case, please do provide some hints, or further reading on how to test if a point is colliding with an object defined by some vertices.
EDIT: The "map" will have objects on it, like trees and houses. I was thinking, maybe even caves. It will also have hills and what-not, but a heightmap is out of the question I guess.
If you're going for a do-it-yourself solution, I'd suggest the following.
Terrain
Preferably have the terrain be a grid, with just each vertex varying in height. The result is a bunch of quads, each with the same dimensions in the (x, y) plane. Vertices have varying (z) values to make up the slopes. The grid arrangement allows you to easily determine which triangles you will have to test for intersection when performing collision checks.
If that's not an option (terrain pre-built in modeling package), you'll probably want to use an in-memory grid anyway, and store a list of triangles that are (partially) inside each cell.
Checking for collision
The easiest approach would be to consider your actors points in space. Then you'd determine the height of the terrain at that point as follows:
Determine grid cell the point is in
Get triangles associated with cell
Get the triangle containing the point (in the (x, y) plane)
Get height of triangle/plane at point
In the case of the "pure grid" terrain, step 3 involves just a single point/plane check to determine which of the 2 triangles we need. Otherwise, you'd have to do a point-in-triangle check for each triangle (you can probably re-use point/plane checks or use BSP for further optimization).
Step 4 pseudo-code:
point = [ x, y, z ] // actor position
relativePt = point - triangle.vertices[0]
normal = triangle.plane.normal
distance = relativePt DOT normal // (this is a dot-product)
intersection = [
point.x,
point.y,
point.z + distance / normal.z ]
This calculates the intersection of the ray straight up/down from the actor position with the triangle's plane. So that's the height of the terrain at that (x, y) position. Then you can simply check if the actor's position is below that height, and if so, set its z-coordinate to the terrain height.
Objects (houses, trees, ... )
Give each object 1 or more convex collision volumes that together roughly correspond to its actual shape (see this page on UDN to see how the Unreal Engine works with collision hulls for objects).
You will have to use some spatial subdivision technique to quickly determine which of all world objects to check for collision when moving an actor. If most movement is in 2 dimensions (for example, just terrain and some houses), you could use a simple grid or a quadtree (which is like a grid with further subdivisions). A 3-dimensional option would be the octree.
The point of the spatial subdivision is the same as with the terrain organized as a grid: To associate place objects with cells/volumes in space so you can determine the set of objects to check for a collision, instead of checking for collision with all objects.
Checking for collision
Get the "potential collision objects" using the spatial subdivision technique you've used; f.e. get the objects in the actor's current grid cell.
For each convex collision volume of each object:
Using the separating axis theorem, determine if the actor intersects with the collision volume. See my answer to a different post for some implementation hints (that question is about the 2D case, but the code largely applies; just read "edge" as "plane").
If collision occurs, use the normal of one of the "offending planes" to move the actor to just next to that plane.
Note: In this case, model your actor's collision volume as a box or 3-sided cylinder or so.
Also, you may want to consider building a BSP tree for each object and use axis-aligned bounding boxes for your actors instead. But that's getting a little beyond the scope of this answer. If your objects will have more complicated collision volumes, that will be faster.
Final thoughts
Well, this is already a really long answer, and these are just some broad strokes. Collision is a pretty broad topic, because there are so many different approaches you can take depending on your needs.
For example, I haven't covered "trace collision", which is detecting collision when an actor moves. Instead, the above suggestion on objects checks if an actor is inside an object. This may or may not suit your needs.
I also just realized I haven't covered actor-vs-actor collision. Perhaps that's best done as colliding 2 circles in the (x, y) plane, with an additional check to see if their vertical spaces intersect.
Anyway, I really gotta wrap this up. Hopefully this will at least point you in the right direction.

Categories