Jump to content

Dynamic line and text


vahith
 Share

Recommended Posts

hi all;
i am trying to draw dynamic line by selecting mouse picking points and  also i want to show the length(size) above the line. How i can achieve this is it possible in babylon.js..?kindly suggest me some test case to achieve this..

thanks

Link to comment
Share on other sites

I'm currently working on kind of the same problematic: I also want to draw a line between two points on an irregular plane, and make the line follow the different heights of the plane while displaying the distance between the two points. So far I managed to display the line between the two points (dynamically, meaning it is showed as soon as you picked the first point, and between the first point and the user cursor) and show the distance in the navigator console when the second point is picked. Also, thanks to a linear interpolation, I managed to make the line follow the irregularities of my plane. Here's the code to do so:

 

//!\\ SEE NEW SHINY AND FULLY COMMENTED VERSION IN THE NEXT ANSWER TO THIS POST :-) //!\\

    var _this = this;    var firstPoint  = null;    var secondPoint = null;    _this._scene.onPointerDown = function(evt, pickInfo){        if(pickInfo.hit){            if(firstPoint){ // meaning: first point already picked                secondPoint = pickInfo.pickedPoint;                var distance = (secondPoint.subtract(firstPoint)).length(); // compute the distance between the two points                console.log(distance); // show the distance in the console                $("#renderCanvas").off("mousemove"); // cancel the event handler you'll see in the else statement below                // reinitialize the firstPoint                firstPoint = null;            } else { // meaning: first point hasn't been picked yet                firstPoint = pickInfo.pickedPoint;                // create new line that will be used to display the distance between the two points                var distanceLine = null;		// update the line displaying when the user moves his mouse on the canvas                $("#renderCanvas").on("mousemove", function(evt){                    if(distanceLine){                        distanceLine.dispose(); // remove the previous drawn line, if there is any                    }                    var mousePickInfo = _this._scene.pick(evt.clientX, evt.clientY, null, null, _this._scene.activeCamera);                    if(mousePickInfo.hit){                        var mousePickedPoint = mousePickInfo.pickedPoint.clone();                        // the following var will be used in the linear interpolation;                         // modify its value for a more precise following of the irregularities of the terrain/plane:                        // a higher value means a higher precision.                        var divider = 100;                         coordinatesArray.push(firstPoint);                        // temporary var used for commodity                        var tempFirstPoint = firstPoint.clone();                        var tempSecondPoint = mousePickedPoint.clone();                        // increase the y position of the temporary points, in order to use them                        // in the linear interpolation                        tempFirstPoint.y += 1000;                        tempSecondPoint.y += 1000;                        // the following array will contain the points of the white line between the two picked points                        var coordinatesArray = []; // Vector3[]                        coordinatesArray.push(firstPoint);                        // LINEAR INTERPOLATION - see BJS doc for more info on BABYLON.Vector3.Lerp                        // and Wikipedia for more on discrete values and linear interpolation                        for(var i = 1; i < divider; i++){                            var tempPoint = BABYLON.Vector3.Lerp(tempFirstPoint, tempSecondPoint, i/divider);                            var minHeight = 0;                            var ray = new BABYLON.Ray(tempPoint, new BABYLON.Vector3(0,-1,0));                            var pickedPointInfo = _this._scene.pickWithRay(ray, null);                            if(pickedPointInfo.hit){                                minHeight = pickedPointInfo.pickedPoint.y;                                // push the point into the correct array                                coordinatesArray.push(new BABYLON.Vector3(tempPoint.x, minHeight, tempPoint.z));                            }                        }                        coordinatesArray.push(mousePickedPoint);                        distanceLine = new BABYLON.Mesh.CreateLines("distanceLine", coordinatesArray, _this._scene);                        distanceLine.color = new BABYLON.Color3(1, 1, 1); // colors the line in white                    }                });            }        }    };
Link to comment
Share on other sites

Hi again! I'm back, with a new, shiny, clean, and fully commented measure tool :-) you should be able to directly copy-paste the following parts of code into your own project and use it as you wish ;-)

 

First, some HTML to insert in your <body>:

<!--Measure Tool Indicator--><div id="measureToolIndicator" class="hidden"></div>

The corresponding CSS:

.hidden{  display : none;}#measureToolIndicator{  position         : absolute;  color            : white; // feel absolutely free to change these...  background-color : black; // ... I'm not really a designer ;-)  z-index          : 10; // just make sure it's above your canvas z-index  pointer-events   : none;}

Now, the good part, the JS :-) first of all, the MeasureTool object with its prototype:

"use strict";/** * The mighty measure tool the user can use to... measure things. Like distance * between two picked points, or the height of a building... In fact, every distance * between two points picked on pickable material on the scene. * @param scene * @constructor */var MeasureTool = function(scene) {    // Determines if the tool is activated/deactivated    this.activated  = false;    // The scene we're working on    this._scene = scene;    // The first clicked point    this.firstPoint = null;};MeasureTool.prototype = {    /**     * Manage the actions of the measure tool     * @param evt     * @param pickInfo     */    manageMeasureTool : function(evt, pickInfo) {        var _this = this;        var distanceLine = null;        if(pickInfo.hit && this.firstPoint){            // cancel the mousemove event; the last drawn line will be left on the scene, until            // you pick an other point            $("#renderCanvas").off("mousemove");            // reinitialize the first picked point, so an other measure can be launched            // by clicking on the scene            this.firstPoint = null;        } else if(pickInfo.hit && !this.firstPoint){            // dispose of any already drawn line on the scene            if(_this._scene.getMeshByName("distanceLine")){                _this._scene.getMeshByName("distanceLine").dispose();            }            // clone the picked point and store it for further purpose            this.firstPoint = pickInfo.pickedPoint.clone();            /**             * Add a mousemove event listener on the canvas, that will draw and display             * the line between your first picked point and your pointer. Also, this event             * will trigger the display of the distance next to your pointer.             */            $("#renderCanvas").on("mousemove", function(evt){                // dispose of any already drawn line on the scene                if(_this._scene.getMeshByName("distanceLine")){                    _this._scene.getMeshByName("distanceLine").dispose();                }                // pick the position of the pointer on the scene                var mousePickInfo = _this._scene.pick(evt.clientX, evt.clientY, null, null, _this._scene.activeCameras[0]);                if(mousePickInfo.hit){                    // clone the point on the scene on which the pointer is                    var mousePickedPoint = mousePickInfo.pickedPoint.clone();                    /**                      * The divider will be used for the linear interpolation below. It will determine the precision of the                     * interpolation, and so the fidelity of the drawn line regarding the different heights of your terrain.                      * The higher it is, the higher the precision will be. But as the linear interpolation is launched each                      * time you move the pointer, it is wiser to keep it relatively low (100 is convenient for my purpose)                     */                    var divider = 100;                    // this array will store every point that will form the drawn line between your first point and the pointer                    var coordinatesArray = []; // Vector3[]                    // push the first picked point into this array                    coordinatesArray.push(_this.firstPoint);                    // for the purpose of the linear interpolation, clone & store the points into                    // temporary Vector3 var, which y position will be increased                    var tempFirstPoint = _this.firstPoint.clone();                    var tempSecondPoint = mousePickedPoint.clone();                    tempFirstPoint.y += 1000;                    tempSecondPoint.y += 1000;                    for(var i = 1; i < divider; i++){                        // linear interpolation                        var tempPoint = BABYLON.Vector3.Lerp(tempFirstPoint, tempSecondPoint, i/divider);                        /**                         * Now, we'll launch a ray from our tempPoint, perpendicularly toward the scene. This ray                         * will pick the first pickable object he will stumble upon (the ground, a building, etc...).                         * That way, it will determine the height of the next point of our drawn line.                         */                        var minHeight = 0;                        var ray = new BABYLON.Ray(tempPoint, new BABYLON.Vector3(0,-1,0));                        var pickedPointInfo = _this._scene.pickWithRay(ray, null);                        if(pickedPointInfo.hit){                            // retrieve the height of the first obstacle found by the ray                            minHeight = pickedPointInfo.pickedPoint.y;                            // push the new point of the line in the coordinates array                            coordinatesArray.push(new BABYLON.Vector3(tempPoint.x, minHeight, tempPoint.z));                        }                    }                    // push the last point, that is to say the point your pointer is pointing on the scene                    coordinatesArray.push(mousePickedPoint);                    // finally create the line                    distanceLine = new BABYLON.Mesh.CreateLines("distanceLine", coordinatesArray, _this._scene);                    // color of the drawn line (here: white)                    distanceLine.color = new BABYLON.Color3(1, 1, 1);                    /** MEASURE TOOL INDICATOR **/                    // compute the distance                    var distance = (mousePickedPoint.subtract(_this.firstPoint)).length();                    // trim the distance value                    distance = distance.toFixed(2);                    // display the distance                    $("#measureToolIndicator").html(distance + "m");                                        $("#measureToolIndicator").removeClass("hidden").css("top", evt.clientY + 10).css("left", evt.clientX + 10);                    /** END MEASURE TOOL INDICATOR **/                }            });        }    }};

Finally, the JS to activate/deactivate and use the measure tool; you'll have to create two controls on your HTML page to activate/deactivate the measure tool (here, I use two buttons with convenient names):

// you may have to precise the following line if you have multiple camera on your scene // (the camera I personally use is the first created - don't forget to change the following if// you have something different!)scene.cameraToUseForPointers = scene.activeCameras[0];var measureTool = new MeasureTool(scene);$("#activation_button").on("click", function(){    measureTool.activated = true;    scene.onPointerDown = function(evt, pickInfo){        measureTool.manageMeasureTool(evt, pickInfo);    };});$("#deactivation_button").on("click", function(){    measureTool.activated = false;    scene.onPointerDown = null;});

Hope this will help you with your problem :-) tell me if you encounter any problem with the code ;-)

Link to comment
Share on other sites

  • 4 years later...
  • 2 months later...

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...