Creating THREE.Line's with different endpoints using THREE.BufferGeometry - three.js

I am creating several THREE.Lines using THREE.BufferGeometry. Initially my app had them all starting at the origin and things worked as expected. Now, I would like to be able to start (and end) them at any point.
This fiddle (http://jsfiddle.net/9nVqU/) illustrates (I hope) how changing one end of the line away from the origin causes unexpected results.
I wondered if it was because any given line follows on from the previous one - switching the start/end order didn't change anything though so if that were true, I'd expect it to break.
Maybe I have the arrays set up incorrectly or the attributes that tell THREE.js how to interpret it - I think I need 2 * 3 verts for each line but changes I made to buffer_geometry.attributes = { seemed to make things worse.
FWIW, the actual effect I'm trying to achieve is to selectively turn on and off the lines based on user input. I can do that already by changing the end position but then I lose that value and I don't want to store it elsewhere. I thought that I could move the start point to the end point to switch it off and then move the start point to the origin again to re-enable it. If there is a way to enable/disable lines individually with BufferGeometry, then that would clearly be better.

First of all, you would have to do this:
var line = new THREE.Line( buffer_geometry, material );
line.type = THREE.LinePieces;
Second, this is not supported in r.58 , but should be.
As a work-around, you can hack WebGLRenderer.renderBufferDirect() like so:
// render lines
setLineWidth( material.linewidth );
var position = geometryAttributes[ "position" ];
primitives = ( object.type === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES;
_gl.drawArrays( primitives, 0, position.numItems / 3 );
_this.info.render.calls ++;
_this.info.render.points += position.numItems;
three.js r.58

Related

three.js Geometry.faceVertexUvs setup is confusing

I am working on implementing a custom model importer. The file contains all the necessary info (vertices, vertex normals, vertex uv coordinates, materials, etc.)
It's important to note that the file contains models with multiple materials.
The setup of the vertices is fairly straight forward and is working correctly.
The setup of the faces I'm not 100% sure about. I do the following:
meshDict[name].faces.push(
new THREE.Face3(parseInt(triangles[t]),
parseInt(triangles[t + 1]),
parseInt(triangles[t + 2]),
[normals[parseInt(triangles[t])],
normals[parseInt(triangles[t + 1])],
normals[parseInt(triangles[t + 2])]],
new THREE.Vector3(1, 1, 1), matIndex));
Here: t is the index iterator of the triangles array, normals is an array that holds the normal information of the vertices and matIndex is the material index of the face based on the sub-mesh number from the object file. This also seems to work correctly.
Now for the hard part. I searched all day for a clear explanation and/or good example of how to set-up the faceVertexUvs of a multi material mesh, but every second post I found shows a different method to set this up. After a lot of trial and error I got to this solution that works, but throws a LOT of warnings...
for (var f = 0; f < faces.length; f++)
{
if (currentMesh.faceVertexUvs[faces[f].materialIndex] == undefined)
{
currentMesh.faceVertexUvs[faces[f].materialIndex] = []
faceOffset = (faces[f].materialIndex == 0? 0 : 1) * f;
}
currentMesh.faceVertexUvs[faces[f].materialIndex].push(f);
currentMesh.faceVertexUvs[faces[f].materialIndex][f - faceOffset] = [];
currentMesh.faceVertexUvs[faces[f].materialIndex][f - faceOffset].push(uvs[faces[f].a]);
currentMesh.faceVertexUvs[faces[f].materialIndex][f - faceOffset].push(uvs[faces[f].b]);
currentMesh.faceVertexUvs[faces[f].materialIndex][f - faceOffset].push(uvs[faces[f].c]);
}
Here uvs is an array of Vector2 of the same length as the vertices array.
Basically I am doing:
faceVertexUvs[materialIndex][faceIndex][uvs[a], uvs[b], uvs[c]].
The number of material indexes is equal to the number of sub-meshes that the object has.
So this solution kinda works OK, but some of the textures are not looking correct (I suspect because the UV mapping of that area is not being set correctly), and I am getting a lot of warnings that say:
Important to note that all the models look OK in the exporting program so the issue is not from there.
Any ideas as to what I am doing wrong here?
So I think I finally managed to figure it out and I got it working correctly, and since the documentation is severely lacking in this area, and the examples are not quite clear I'll post my understanding of this topic here for anyone having the same issue.
So it goes like this:
Geometry.faveVertexUvs[UV LAYER][face index][uv[face.a], uv[face.b], uv[face.c]]
As far as I understand unless you have an AO (ambient occlusion) map, you only use UV LAYER 0.
Now, if you define a material index when setting up the faces of the geometry then each face will be rendered with the corresponding material, and there is no need to split the UVs into separate areas like I was doing in my question. So you only have to use:
Geometry.faces.push(new THREE.Face3(v0, v1, v2, [n0, n1, n2], vertexColor, materialIndex));

Physijs stops updating?

I'm trying to make a small project using Three.js & the physics plugin physijs; just a little dice roller. My approach is to use setGravity to move the dice around, modelling gravity to move the dice around. The issue I'm running into is that once the dice come to a rest, they no longer respond to gravity. Has anyone run into this before?
Whats happening:
Ammo.js, on which Physijs is based, puts resting or very slow moving objects in a sleep state to save performance. So when you change the worlds gravity the sleeping objects dont care, because Physijs doesnt tell them gravity has changed.
You have the ability to modify the sleeping thresholds, set activation states or just quickly activate the rigid bodys before changing gravity.
Please note this code applys to native Ammo.js, I am not sure how to
do this when using physijs but you get the idea.
Solution 1: Loop over your Bodys and activate them, then change gravity:
// dice is an array with your rigid bodys
for ( var i = 0; i < dice.length; i ++ ) {
// hey wake up
dice[ i ].activate();
}
physicsWorld.setGravity( new Ammo.btVector3( 0, -9.81, 0 ) );
Solution 2: Thou shall get no sleep, do this after creating your dice:
var DISABLE_DEACTIVATION = 4;
for ( var i = 0; i < dice.length; i ++ )
// no sleep for you... ever
dice[ i ].setActivationState( DISABLE_DEACTIVATION );
}

Parallax Scrolling SpriteKit

I have found a tutorial on parallax scrolling in spritekit using objective-C though I have been trying to port it to swift without much success, very little in fact.
Parallax Scrolling
Does anyone have any other tutorials or methods of doing parallax scrolling in swift.
This is a SUPER simple way of starting a parallax background. WITH SKACTIONS! I am hoping it helps you understand the basics before moving to a harder but more effective way of coding this.
So I'll start with the code that get a background moving and then you try duplicating the code for the foreground or objects you want to put in your scene.
//declare ground picture. If Your putting this image over the top of another image (use a png file).
var groundImage = SKTexture(imageNamed: "background.jpg")
//make your SKActions that will move the image across the screen. this one goes from right to left.
var moveBackground = SKAction.moveByX(-groundImage.size().width, y: 0, duration: NSTimeInterval(0.01 * groundImage.size().width))
//This resets the image to begin again on the right side.
var resetBackGround = SKAction.moveByX(groundImage.size().width, y: 0, duration: 0.0)
//this moves the image run forever and put the action in the correct sequence.
var moveBackgoundForever = SKAction.repeatActionForever(SKAction.sequence([moveBackground, resetBackGround]))
//then run a for loop to make the images line up end to end.
for var i:CGFloat = 0; i<2 + self.frame.size.width / (groundImage.size().width); ++i {
var sprite = SKSpriteNode(texture: groundImage)
sprite.position = CGPointMake(i * sprite.size.width, sprite.size.height / 2)
sprite.runAction(moveBackgoundForever)
self.addChild(sprite)
}
}
//once this is done repeat for a forground or other items but them run at a different speed.
/*make sure your pictures line up visually end to end. Just duplicating this code will NOT work as you will see but it is a starting point. hint. if your using items like simple obstructions then using actions to spawns a function that creates that obstruction maybe a good way to go too. If there are more then two separate parallax objects then using an array for those objects would help performance. There are many ways to handle this so my point is simple: If you can't port it from ObjectiveC then rethink it in Swift. Good luck!

How to draw a new line on Gtk::DrawingArea area, while peristing previous lines that have already been drawn?

I am using C++11 with GNU tool chain with gtkmm3, on Ubuntu 12.04 LTS 32 bit.
I have been playing wtih some of the examples for gtkmm3 in Programming with gtkmm 3.
Based on 17.2.1.Example there, I inherited from Gtk::DrawingArea (MyDrawingArea here) and overrode the on_draw() event handler as follows:
MyDrawingArea.hpp
...
protected:
bool on_draw ( const Cairo::RefPtr<Cairo::Context>& cr ) override;
MyDrawingArea.cpp
bool MyDrawingArea::on_draw( const Cairo::RefPtr<Cairo::Context>& cr )
{
Gtk::Allocation allocation = get_allocation( );
const int width = allocation.get_width( );
const int height = allocation.get_height( );
int coord1{ height - 3 };
cr->set_line_width( 3.0 );
this->get_window( )->freeze_updates( );
cr->set_source_rgb( 0, 0.40, 0.60 );
cr->move_to( 0, coord1 );
cr->line_to( width, coord1 );
cr->stroke( );
cr->set_source_rgb( 1, 0.05, 1 );
cr->move_to( mXStart, coord1 );
cr->line_to( mXStart, mYAxis * 1.5 );
cr->show_text( to_string( mYAxis ) );
cr->stroke( );
mXStart += 5;
this->get_window( )->thaw_updates( );
return true;
}
My goal is to draw a simple bar graph based on a calculation I do in a little test application, the idea being that each time the on_draw() event is called, the next bar would be moved 5 units to the right on mXAxis and a vertical line would be drawn based on the new mYaxis value, which is computed based on the results of the new calculation.
When I want to repaint my graph and trigger the MyDrawingArea::on_draw() event, I call MyDrawingArea.show_all() from my application after the calculation has completed, and new x and y axes have been set.
However, this does not work as I expected: MyDrawingArea.show_all() invalidates the entire drawing window and draws from scratch: the new graph line appears in its proper place, but the previous ones are erased. I also tried MyDrawingArea.queue_draw(), which had the same effect. But I want to persist the previous graph results so I can get a profile of the calculation results, as I calculate with different values.
This implementation is also causing the bottom line on my graph (my x axis on the graph)- drawn by the first stroke() call in my code example, to be rendered anew on each call to on_draw() - although this should not be necassary since this line persists for the lifetime of MyDrawingArea - it should not be necessary to invalidate and then re-draw it on each new on_draw() event, as my code is currently doing, because I am haven't yet found a way to handle this.
I am very new to Cairo, so I'm sure I'm probably doing this completely wrong, but explicit, task-oriented documentation appears to be sparse - have not found anything that explains how to do this, although I'm sure it is quite simple.
What do I need to do to draw a new line on Gtk::DrawingArea, while persisting previous graph lines that have already been drawn on previous passes, and establish graphics elements that will persist for the lifetime of the Gtk::DrawingArea widget. Obviously using show_all() or queue_draw() and doing it all in the on_draw() event is not the way to go.
In general, you must draw the entire widget and Cairo will clip the drawing to the predefined dirty region. See also GTK reference manual for the "GtkWidget::draw" signal for performance tips:
The signal handler will get a cr with a clip region already set to the
widget's dirty region, i.e. to the area that needs repainting.
Complicated widgets that want to avoid redrawing themselves completely
can get the full extents of the clip region with
gdk_cairo_get_clip_rectangle(), or they can get a finer-grained
representation of the dirty region with
cairo_copy_clip_rectangle_list().
So you may be able to redraw only the region you want with gtk_widget_queue_draw_area().

Three.js - how can I update an arrowHelper?

I'm trying to update an arrowHelper. I've tried manipulating the vertices in the arrow object's line, setting everything dynamic = true and so on, but the only way I can seem to do it is by removing the old line and drawing a new one. Is there a way to update an arrowHelper?
So you can't update an arrowHelper per se in the usual way you update something, by changing the values you used to create the object.
However: you can move the arrow's position, which moves its apparent start point, and you can give it a new direction and length, which moves its apparent end point.
Here's how to do it:
// new arrowHelper
var sourcePos = new THREE.Vector3(0, 0, 0);
var targetPos = new THREE.Vector3(0, 50, 0);
var direction = new THREE.Vector3().sub(targetPos, sourcePos);
var arrow = new THREE.ArrowHelper(direction.clone().normalize(), sourcePos, direction.length(), 0x00ff00);
scene.add(arrow);
// update the arrow
var newSourcePos = new THREE.Vector3(10, 10, 10);
var newTargetPos = new THREE.Vector3(60, 10, 10);
arrow.position.set(newSourcePos);
direction = new THREE.Vector3().sub(newTargetPos, newSourcePos);
arrow.setDirection(direction.normalize());
arrow.setLength(direction.length());
Thanks to the folks who answered this question, it certainly helped me. There are a couple of small problems with it that folks will want to avoid:
Calling direction.normalize() in the penultimate line of code changes the direction vector to a unit vector and thus the original length is lost. You can change the order of the last two lines, setting the arrow length from the unmodified direction vector, or (perhaps clearer) you can save its length in a separate variable. Without some such modification, though, the arrow will always be set to unit length.
In addition, the function arrow.setLength(length, headLength, headWidth) accepts two arguments beyond those shown in the answer (perhaps this has changed since this was written?). Accepting defaults for headLength and headWidth by not supplying explicit values in the call will result in overwriting any non-default values that might have been supplied in the constructor (rather than keeping the values as they are set).

Resources