Jump to content

tube mesh


jerome
 Share

Recommended Posts

mmmh.. this tube gives me some idea to implement a more general extrusion system

 

Given a curve and another small array of vector3 representing, say, a 2D shape (like we could do when drawing with createLines() ), it could then extrude this shape along the curve

 

something like  :

extrudeCurve(curve, shape, scene);

curve = array of vector3

shape = array of vector3 (a star, a puzzle piece, whatever)

 

no tesselation needed because the shape vectors define the radial segments, no radius either 

 

I'll think about it this week-end :huh:

Link to comment
Share on other sites

Hi folks

 

Before I clean the tube code and at last try to convert to TS before submit a PR (I hope), here is a very last feature I wanted to add without making the call signature too complex.

Here is the new call signature :

createTube(curve, radius, tesselation, radiusFunction, scene);

So not a big change :

 

  • curve : still the path to extrude the tube along
  • radius : tube radius
  • tesselation : radial segment number
  • scene : current scene

 

But there is a new optional parameter "radiusFunction"

Ok, if you set radiusFunction to null, you'll get your usual tube as former example : http://www.babylonjs-playground.com/#1W1TVT#7

 

So what is this parameter for ?

It allows to set a function to be called each point of the curve to modify the tube radius on this point according to its index in the curve array.

 

Not clear ?

 

Say, I want to deform my tube to give it some bubbles. It means the radius should change many times along the curve according a sinus function for example

Right ?

 

Say, I want 80 bubbles along my tube, so I just create the following function returning the radius value for each call (i is the curve vector3 index in the curve array)

  var radiusFunction = function(i) {    var step = Math.PI / curve.length * 80;    var radius = 1 + 0.5 * Math.sin(step*i);    return radius;  };

Quite simple, mmh ?

 

I can then call my createTube function this way : 

createTube(curve, 1, 30, radiusFunction, scene);

the radius parameter value is then ignored and the radiusFunction is applyed to each point.

 

Still obscure ?

 

Have a look : http://www.babylonjs-playground.com/#1W1TVT#6

Link to comment
Share on other sites

the radiusFunction just needs to return the current radius

it is not mandatory to be a continuous function : http://www.babylonjs-playground.com/#1W1TVT#8

 

ex : no bubble in the middle of the tube ...

    var radiusFunction = function(i) {        var radius;        if ( i > 150 && i < 450 ) {            radius = 0.8;             }        else {            var step = Math.PI / curve.length * 80;            radius = 1 + 0.5 * Math.sin(step*i);        }    return radius;    };
Link to comment
Share on other sites

I once had a hangover that felt exactly like that looks.  :)

 

To be blunt, I can't imagine a practical use for this shape.  It's artful, and fascinating, but I don't really understand the bowtie path, nor the need for clumps in this bowel.  hehe.  I hope I'm not being mean or discouraging.  It just seems that it has wandered away-from "basic shape" if that is an objective. 

 

But it fits with Spherical Harmonics in an "advanced shapes" category, I would think. I am just having problems imagining when/how it would be used in a scene, other than maybe being a fascinating object to stumble-upon during an adventure through Meshville.  :)

Link to comment
Share on other sites

it's just an example... my shape is really useless !

:D :D :D

 

The basic shape is the tube along a curve. This fits a real need.

You sometimes may want this tube to be just a bit parametrable, to have the radius change after a certain length or to fit a dedicated math or conditional function.

So that's what this parameter is for :P

Link to comment
Share on other sites

Well, imagine a cartoon like scene where ... lets say the coyote is pumping gas into his monster truck for a race with the road runner. The tube is pumping the gas into this really cool monster truck (the bumps are animated in my imagination and follow the tube just like the gasoline would).Meanwhile the road runner passes by so fast that the road catches fire and a track of gasoline catches fire and slowly burns in the direction of the gas station which will explode in the next second... in the distance you hear a *miep*miep*

 

... no practical use he says *tz* ;)

Link to comment
Share on other sites

see : http://www.babylonjs-playground.com/#1W1TVT#10

 

I just tell the radius to increase +0.01 each curve point

  // radius function    var radiusFunction = function(i) {      var radius = 1 + 0.01 * i;      return radius;    };

and then just a line of code to generate this complex shape !

 

still useless ? ;)

Link to comment
Share on other sites

Now I add some really simple condition upon i

    var radiusFunction = function(i) {        var radius = 1;        if ( i > 500 ) {            radius = 1 + 0.01 * i;        }    return radius;    };

and I get a corckscrew with just one call :lol: : http://www.babylonjs-playground.com/#1W1TVT#11

Cheeeeeeerrssss

Link to comment
Share on other sites

I think the radius function can be quite useful. For example this might allow you to do nice visual effects, by mapping an alpha blended and/or additive texture on it. This could do a nice smoke trail, or a fire spray, that you could then further transform with a shader.

 

What I'd suggest is that the radius functions also provides a "current distance" argument. If you look at this example, you can see that the lumps are squeezed at the center of the shape, and I guess that is because segments are shorter there. It'd be nice to be able to modify the radius independently of the distance between each segment.

 

Something like: 

    var radiusFunction = function(index, distance) {        var radius = 1;                // do something according to current index, or current distance to first segment        return radius;    };
Link to comment
Share on other sites

you are right, segments are shorter in the center because of the math function

 

ok

So if distance is set to null, the index parameter would be used

and if the index is set to null, the distance parameter (say, the ratio from the start to the end of the curve, ex : 0.6 would 60% from the start) would be used instead

 

Did I understand well ?

 

I need to find a way to compute this distance now, I have already a tiny idea how to do it in a simple way ;)

Link to comment
Share on other sites

I was thinking of something more simple: the radius function is called with both parameters, and the user is free to use one or the other, or both.

 

Also the ratio from the start to the end may be a good idea too. I don't really know what would be best. I first suggested the "distance" parameter (which would be the sum of all the previous segments length) because I've been coding quad ribbons a lot in 2D and computing the distance from the start allowed me to correctly map a texture on it and apply smooth deformations.

 

Think about it: after all, your mesh builder may be used to show a trail after a ship or a vehicle, for which there would be no reason for the intervals between its positions to be regular (FPS variation, acceleration). Having a "distance" parameter in the radius function would allow to make smooth curves on the trail, regardless of interval discrepancies.

 

Also using a percentage of the total length will scale any deformation you make on the mesh, whereas using the current distance to start will not. I guess it would make sense to offer both...

Link to comment
Share on other sites

good arguments !

 

though I don't really understand how to show a trail with a tube  :D

 

Or maybe could I pass three arguments : index, current distance, current ratio. 

I had the idea about the ratio because I think the user can't know the real curve length unless computing it by himself (ex : I'd like to apply some radius deformation after 53% of the curve length - yes, 53, accuretly, why not? - ).

I wanted the tube mesh to be easy to use and as versatile as possible to be able to generate the maximum derivated shapes : a simple basic shape with extensible capabilities.

 

So ok for the distance, I'll try tomorrow  ;)

 

Just like I intend to design the ribbon too  :P

Link to comment
Share on other sites

A tube with alpha-blended smoke texture on it, maybe another one around it. Or a nice flamethrower effect, where the tube would "link" particles sent by the weapon.

 

Also, viewed from the inside it could be used as an environment, for example around a car in a race game. Or around a space ship going through hyperdrive.

 

What I'm currently wondering is the performance hit of rebuilding a mesh every frame. Would be worth a try!

Link to comment
Share on other sites

I don't think rebuilding or recreating a new mesh every frame is the right way to do. :mellow:

Maybe could we instead just set new positions in the vertexdata object without changing indices ? ok, it's a kind of rebuild but very light as the face declaration is not changed, only vertex positions.

 

I should give try on this way.. though I have at this very moment absolutly no idea how this is doable  :D

Are there mesh object abstract methods to set new positions ?

Should I have to access the underlying vertexData object (or implement this kind of abstract method at mesh level) ?

Is an updated existing vertexData object rendered with its new fresh positions ?

What if the related mesh has been rotated or translated in the world axis inbetween ?

So many questions !!! :o

 

I guess there's always the shader way to do elseway  ^_^

 

 

need to fix a bug (unexpected twist on a path with curve inversions) in the tube before... pffff, my design can't resist a simple sinus curve  :(

Link to comment
Share on other sites

ok, bug fixed and refactored... I had to improve my first design with this method : http://www.cs.cmu.edu/afs/andrew/scs/cs/15-462/web/old/asst2camera.html

(it seems I wasn't alone to face this problem)

 

here : http://www.babylonjs-playground.com/#2FU48M

 

Scene starts at line 195, forget the content above ;) unless you want to visualize the mesh (line 163 => true and comment line 167) or the design vectors (uncomment line 154)

 

 

Please test your own simple or complex curves to stress the design : line 219 if you want some math function

But you can use whatever path (array of successive vector3) you want

Link to comment
Share on other sites

Hey Jahow, here is your radius function with distance parameter : http://www.babylonjs-playground.com/#1SXGPW

 

Scene from line 200.

 var radiusFunction = function(i, distance) {    var radius = 1 + 0.5 * Math.sin(distance/2.5);    return radius;  };  createTube(curve, 1, 20, radiusFunction, scene);

As you can see, now the lumps are not bound to indexes any longer. They spawn in function of the distance from the beginning of the tube.

There is no longer the short segment effect.

 

Hope you like ;)

 

I still have to implement (if i can succeed) the close feature : tube joint at start and end

Link to comment
Share on other sites

  var curvePoints = function(l, t) {  var path = [];  var step = l / t;  for (var i = -l/2; i <= l/2; i += step ) {    path.push(new BABYLON.Vector3(i, 12 * Math.sin(i/10), 0 ));    }    return path;  }; var curve = curvePoints(40, 300);  var radiusFunction = function(i, distance) {    //var radius = 1 + 0.5 * Math.sin(distance/2.5);    var radius =  Math.exp(distance * distance / 1000);    return radius;  };  createTube(curve, 1, 40, radiusFunction, scene);

a sinus for the curve, a  exponential(distance²) for the radius et voilà : http://www.babylonjs-playground.com/#1SXGPW#1

Link to comment
Share on other sites

I wish I can see what you are imaginating with your trails, on so on  ;)

 

The tube and the ribbon mesh (needed for the tube) are still in progress though quite complete (need uv and optional close feature for ribbon, maybe coded today and close feature for the tube too)

 

You can have both here for now (evolving prototypes) :

http://logiciels.iut-rodez.fr/proto/weathermap/test2/ribbonMesh.js

http://logiciels.iut-rodez.fr/proto/weathermap/test2/tubeMesh.js

 

 

[EDIT]

I read a bit about the problematic to close tubes (to avoid a twist between first and last pattern).

Seems really complex :huh:

http://research.microsoft.com/en-us/um/people/yangliu/publication/computation%20of%20rotation%20minimizing%20frames.pdf

http://www.cs.hku.hk/research/techreps/document/TR-2007-07.pdf

http://www.cs.indiana.edu/pub/techreports/TR425.pdf

 

So, I am not sure I will implement this feature for now :(

[/EDIT]

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...