How can you surround a mesh with a skin?

Sometimes interesting structures arise at work. They look like skeletons.


https://www.behance.net/gallery/83236997/Constructor

I would like to surround these constructions with a skin. It would also be optimal to integrate the “musculature” under the skin.

Is there a separate function in babylon.js or does someone know a library that can do this?

2 Likes

I think I found a way to do that with a ribbon
https://doc.babylonjs.com/how_to/ribbon_tutorial

image
https://www.babylonjs-playground.com/#1W5VJN#71

image
https://www.babylonjs-playground.com/#1W5VJN#72

But it is not the right thing I’m looking for.

I need something similar like these meta bubbles created with three.js

https://stemkoski.github.io/Three.js/Metabubbles.html

or this one:
https://stemkoski.github.io/Three.js/Metaballs.html

Here we are a bit closer to the solution for a harmonic skin generation: 3D-Splines!


https://www.babylonjs-playground.com/#1GXSPK#25

This is exactly what I need for my little project “constructions of life forms”:

image

English:

and this is a library I found now:

Well, another challenge to merge that with bablyon js. :slight_smile:

1 Like

Hi Necips, I had a similar challenge.

SOLUTION: polyrubber.

It is a ribbon with edit nodes on every vertex (and master edit for entire ribbon) so that it can be formed (stretched) to any shape.

The concept is similar to 3D retopolation (but in BJS).

For my purposes I used polyrubber to make sand dunes, and “skin” around a space ship, and checkCollisions = true, remains at 60fps.

Here is code from within namespace (make it hard to export to playground) but gives Idea to see if it is what you need (tricky), and to get started if you need it:



nx.polyRubber = {}; //contains the many helper functions required to edit polyrubber-.
nx.polyRubber.DEFAULTVERTSTACK3X3 = [  
[{x:10,y:0,z:10},{x:0,y:0,z:10},{x:-10,y:0,z:10}],
[{x:10,y:0,z:0},{x:0,y:0,z:0},{x:-10,y:0,z:0}],
[{x:10,y:0,z:-10},{x:0,y:0,z:-10},{x:-10,y:0,z:-10}]
]

nx.polyRubber.createPolyRubberEditor = function( config ){ 
	//USAGE: nx.polyRubber.createPolyRubberEditor({aMesh:nx.topConnector}); //GOOD-polyrubber-RIBBON-EDITOR-.;
	//DESCRIPTION: a PLANE that can expand and be edited into any shape-.

    //CONFIG: {aMesh:nx.topConnector}
    if(!config.aMesh){ return; }
    nx.polyRubber.mesh = config.aMesh;
    nx.polyRubber.positions = nx.polyRubber.mesh.getVerticesData(BABYLON.VertexBuffer.PositionKind); //extra for ribbon
    nx.polyRubber.indices = nx.polyRubber.mesh.getIndices();
    nx.polyRubber.normals = [];

    //--------------POINT-EDIT-------------------------------------------------------------------------------------------
    nx.polyRubber.editNodes = [];
    for (var i=0; i < nx.polyRubber.positions.length; i+=3){
        var editNode = BABYLON.Mesh.CreateSphere("editNode"+i, 1, 0.5, nx.scene);
        editNode.editMode = 0;
        editNode.vectorIndex = i;
        editNode.material = nx.blueMat;
        editNode.position = new BABYLON.Vector3(nx.polyRubber.positions[i],nx.polyRubber.positions[i+1],nx.polyRubber.positions[i+2])
        nx.polyRubber.editNodes.push(editNode)
        editNode.parent = config.aMesh;
        editNode.editFn = function(){ //---------TEN-KEY-EVENTS--------------------------------------------------------------------------.
            var direction = (nx.ctrl.num8 || nx.ctrl.num6 || nx.ctrl.num7 || nx.ctrl.plus) ? 1 : (nx.ctrl.num4 || nx.ctrl.num2 || nx.ctrl.num9 || nx.ctrl.minus) ? -1 : 0;
            nx.ctrl.mag = (nx.ctrl.alt)? 0.01 : 0.1;
            var moveAmount = nx.ctrl.mag * direction;
            if(this.editMode==="greenEdit"){

                if(nx.ctrl.num8 || nx.ctrl.num2){ this.position.z += moveAmount; 
                    nx.polyRubber.positions[this.vectorIndex+2] += moveAmount;
                }
                if(nx.ctrl.num4 || nx.ctrl.num6){ this.position.x += moveAmount; 
                    nx.polyRubber.positions[this.vectorIndex+0] += moveAmount;
                }
                if(nx.ctrl.plus || nx.ctrl.minus){ this.position.y += moveAmount; 
                    nx.polyRubber.positions[this.vectorIndex+1] += moveAmount;
                }
                nx.polyRubber.positions = nx.editz.truncatePathPrecision(nx.polyRubber.positions); //TRUNCATE-DIRECTLY AFTER EDITZ-.
                nx.polyRubber.updateMeshEdits(nx.polyRubber.mesh, nx.polyRubber.positions, nx.polyRubber.normals, nx.polyRubber.indices)
            }
        }
        editNode.actionManager = new BABYLON.ActionManager(nx.scene); //--MESH-CLICK-EVENTS---------------------------------------------.
        editNode.actionManager.registerAction(new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPickTrigger, function (evt) {
            var eNode = evt.meshUnderPointer;
            if(!eNode){ return; } 
            if(!eNode.editMode){  //MODE-ITERATOR-.
                nx.activeEditNodes.push(eNode);
                eNode.material = nx.greenMat;
                eNode.editMode='greenEdit'
            }else if(eNode.editMode === 'greenEdit' ){
                eNode.material = nx.blueMat;
                eNode.editMode=0
                nx.activeEditNodes.splice(nx.activeEditNodes.indexOf(eNode),1) //deselect
            }
        }));
        nx.editNodes.push(editNode);
    }
    //--------------END-POINT-EDIT-------------------------------------------------------------------------------------------

    if(nx.polyRubber.createMasterEditor){ nx.polyRubber.createMasterEditor(nx.polyRubber); }  //create EDIT MASTER-.

}

It is a factory pattern, so can be attached (as editor) to any mesh at any time:
//USAGE: nx.polyRubber.createPolyRubberEditor({aMesh:nx.someRibbon});

Also you might be able to set custom ellipsoid imposters around points parented to the mesh:


    //BUGZ-COLLISIONS-. Ellipsoid Imposter.
    var bugScaleFactor = 1;
    var bugNoseLength = 3.2 * bugScaleFactor;
    var bugHeightControl = 1.50 * bugScaleFactor;// 1.35;//y axis of both makes for hover height 2.5 too low it hits dirt.
    var bugHoverClearance = 1.55 * bugScaleFactor; //allows hover over bumps.
    nx.hero.Bug1.ellipsoid = new BABYLON.Vector3(2, bugHeightControl, bugNoseLength);  
    nx.hero.Bug1.ellipsoidOffset = new BABYLON.Vector3(-1, bugHoverClearance, 0); //todo
        //DIAGNOSTICS: bounding info
        // nx.hero.spaceBug1.showBoundingBox = true;
        // var x = meshPlayer.getBoundingInfo();
    if(nx.anmz && nx.anmz.hero){nx.anmz.hero.collisionItems.push(nx.hero.Bug1H);} //collision-.
    if(nx.anmz && nx.anmz.hero){nx.anmz.hero.collisionItems.push(nx.hero.Bug1);} //collision-.
    if(nx.anmz && nx.anmz.hero){nx.anmz.hero.collisionItems.push(nx.hero.Bug1T);} //collision-.

there are some predefined curves in BJS : Draw Curves - Babylon.js Documentation

2 Likes

Thank you aFalcon, I came so far … not sure how to get now a new shape out of a plane mesh. Please kick me in the right direction… :slight_smile:

https://www.babylonjs-playground.com/#60NAVI

1 Like

@jerome - that is a favorite doc. :slight_smile:

@Necips try CreateRibbon()

2 Likes

Wow, thank you for the kick-off! :smiley:

So many new things to learn. I’ll do my best.

2 Likes

After I deleted all unessential information and removed redundant data only one statement remained which makes all the magic I needed: CreateRibbon! :smiley:

image
https://www.babylonjs-playground.com/#E6IX1#6


https://www.babylonjs-playground.com/#1HSC2O#10

Detail information :
https://doc.babylonjs.com/how_to/ribbon_tutorial

3 Likes