vahith Posted April 7, 2015 Share Posted April 7, 2015 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 Quote Link to comment Share on other sites More sharing options...
TheFrenchieCake Posted April 7, 2015 Share Posted April 7, 2015 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 } }); } } }; Temechon 1 Quote Link to comment Share on other sites More sharing options...
TheFrenchieCake Posted April 9, 2015 Share Posted April 9, 2015 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 ;-) Temechon and Jaskar 2 Quote Link to comment Share on other sites More sharing options...
vahith Posted April 10, 2015 Author Share Posted April 10, 2015 hi Frenchie, thanks for your solution... i made some demo in playground actually what i am trying to achieve is i want to create dynamic wall when i select two points....check this play ground for creating lines..http://www.babylonjs-playground.com/#1RCIXM#1and if u having any playground demo..?kindly suggest me..thanks Quote Link to comment Share on other sites More sharing options...
TheFrenchieCake Posted April 10, 2015 Share Posted April 10, 2015 Do you want the wall to appear dynamically as you move your mouse over the canvas? Or do you want it to be displayed only when the second point is picked? I don't think I'll have much time to work on it today, maybe this WE if I get motivated enough x) Quote Link to comment Share on other sites More sharing options...
vahith Posted April 11, 2015 Author Share Posted April 11, 2015 hi frenchie.. thanks for response. wall should appear when second point is picked... Quote Link to comment Share on other sites More sharing options...
Jaskar Posted April 11, 2015 Share Posted April 11, 2015 Hi, So, in your playground, you got it ?Do you need more help ? Wingnut 1 Quote Link to comment Share on other sites More sharing options...
vahith Posted April 12, 2015 Author Share Posted April 12, 2015 hi jaskar, yet i didn't find any thing regarding above.. if possible kindly suggest me .. Quote Link to comment Share on other sites More sharing options...
Jaskar Posted April 14, 2015 Share Posted April 14, 2015 Hi, What do you want to add to this playground ? http://www.babylonjs-playground.com/#1RCIXM#1I don't understand. You have your dynamic wall and the measure. Quote Link to comment Share on other sites More sharing options...
vahith Posted April 15, 2015 Author Share Posted April 15, 2015 hi jaskar,thanks for your reply. In above playground i creating line by selecting mouse point but what i trying is i want to create wall on mouse picking position.. could you suggest me how i can achieve... Quote Link to comment Share on other sites More sharing options...
Jaskar Posted April 15, 2015 Share Posted April 15, 2015 Hi, I start a playground here : http://www.babylonjs-playground.com/#1U68CDIt's a start for your idea, but I have no more time today to work on it. Hope it'll be helpfull for you Quote Link to comment Share on other sites More sharing options...
Jaskar Posted April 16, 2015 Share Posted April 16, 2015 I update the playground for you (correct the x scaling of the wall) :http://www.babylonjs-playground.com/#1U68CD#1It something react weird, due to the view, but I think you can do it * Edit : Do not put your cursor out of the ground, or it'll fail vahith and Temechon 2 Quote Link to comment Share on other sites More sharing options...
Temechon Posted April 16, 2015 Share Posted April 16, 2015 The wall should be set in isPickable = false to avoid stuttering : http://www.babylonjs-playground.com/#1U68CD#2 Nice work anyway Jaskar and vahith 2 Quote Link to comment Share on other sites More sharing options...
gogoulor Posted July 6, 2019 Share Posted July 6, 2019 Just a little improved https://www.babylonjs-playground.com/#1U68CD#22 in order to put some grain of sand. Regards Quote Link to comment Share on other sites More sharing options...
Guest Posted September 26, 2019 Share Posted September 26, 2019 Please post your question on the new forum:https://forum.babylonjs.com/ Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.