JackFalcon Posted December 11, 2017 Share Posted December 11, 2017 Hello, Does anyone know how to create a path or lines, in a closed loop, in the shape of an Infinity Symbol? I am pretty sure I saw one in the playground, but cannot find it now. For example: Gerono OR Bernoulli: https://gamedev.stackexchange.com/questions/43691/how-can-i-move-an-object-in-an-infinity-or-figure-8-trajectory The Parameterization is said to be with the following equation: x = cos(t); y = sin(2*t) / 2; I ran into a few errors trying to populate it on the first quick attempt.... Any advice on how to populate Gerono parameterization into the following track (editPoints)? var track = BABYLON.MeshBuilder.CreateLines('track', {points: editPoints}, scene); Quote Link to comment Share on other sites More sharing options...
JohnK Posted December 11, 2017 Share Posted December 11, 2017 Would have appreciated seeing a PG of your first attempt as more than likely it was pretty close to this https://www.babylonjs-playground.com/#3NYWX5#2 and just needed a bit of tweaking . JackFalcon and jerome 2 Quote Link to comment Share on other sites More sharing options...
MarianG Posted December 11, 2017 Share Posted December 11, 2017 And the moving https://www.babylonjs-playground.com/#3NYWX5#3 JohnK and JackFalcon 2 Quote Link to comment Share on other sites More sharing options...
JackFalcon Posted December 11, 2017 Author Share Posted December 11, 2017 @JohnK and @bulisor ... elegant! Gerono and Bernoulli? Wow... extra-credit. Can't wait to learn... Attempted algorithm missing this part: t < 2 * Math.PI; t += Math.PI / 36 Oh! Oh, wow... gets it now, thanks! Far better than "lets draw infinity" attempt (with editable paths). Path-Editing holds secondary use ... JohnK, playground (PBTs) in progress... ... afalcon on a vector. [thanks again]. Quote Link to comment Share on other sites More sharing options...
JackFalcon Posted December 12, 2017 Author Share Posted December 12, 2017 Intriguing extension...to this awesome math. How to govern the speed of the animated cube? Guesses to follow.... . #1 increase number of points, OR drag the frame-rate... but there has to be a better way. What is the most elegant and performant way to govern the speed of the animated box? After that, solutions available on Motion-Path ORIENTATION (using LookAt) and ROLL on curve. Thx: @JohnK & @bulisor Quote Link to comment Share on other sites More sharing options...
JackFalcon Posted December 12, 2017 Author Share Posted December 12, 2017 TWEEN between curve points...? <testing> Looks deeper into those PATH points... A nice function for adding editable points to each curve vertex: /**********************************SHOW-EDIT-NODES*****************************/ // Example: showEditNodes(points,{type:'box', size:0.25}) var showEditNodes = function (points, config){ var numNodes = points.length; var editType = config.type || "box"; var editSize = config.size || 1; var editNode; var greenMat = new BABYLON.StandardMaterial("green1", scene); greenMat.diffuseColor = new BABYLON.Color3(0, 1, 0); var redMat = new BABYLON.StandardMaterial("red1", scene); redMat.diffuseColor = new BABYLON.Color3(1, 0, 0); var blueMat = new BABYLON.StandardMaterial("blue1", scene); blueMat.diffuseColor = new BABYLON.Color3(0, 0, 1); for (var i=0; i < numNodes; i++){ if(editType==='box'){ editNode = BABYLON.Mesh.CreateBox("cube" + i, 0.25, scene); }else if(editType==='sphere'){ // Parameters: name, subdivs, size, scene editNode = BABYLON.Mesh.CreateSphere("editNode"+i, 1, 0.75, scene); } //position-editNodes. editNode.position = points[i]; //init-edit-state-. editNode.actionManager = new BABYLON.ActionManager(scene); editNode.editMode = "none"; editNode.vectorIndex = i; editNode.actionManager.registerAction(new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPickTrigger, function (evt) { var eNode = evt.meshUnderPointer; if(eNode.editMode === 'none' ){ eNode.material = greenMat; eNode.editMode='green' selectedEditNodes.push(eNode); }else if(eNode.editMode === 'green' ){ eNode.material = blueMat; eNode.editMode='blue' }else if(eNode.editMode === 'blue' ){ eNode.material = redMat; eNode.editMode='red' }else if(eNode.editMode === 'red' ){ eNode.material = null; eNode.editMode='none' } if(eNode.editMode!="none"){ displayMeshAxis(eNode, false) } else { displayMeshAxis(eNode, true) var remove = selectedEditNodes.indexOf(eNode) //selectedEditNodes.splice(remove,1) } })); } } Happy to provide displayMeshAxis and the events that edit nodes if you'd like... Quote Link to comment Share on other sites More sharing options...
JackFalcon Posted December 12, 2017 Author Share Posted December 12, 2017 SPEED Study... Thinking about a FrameGovernor... for Christmas. Going to use it for ... rays. Not so good for animating movements (while it does slow things down, so tried it): var index = 0; var biFrameGovernor = 0; scene.registerBeforeRender(function () { biFrameGovernor++; if(!(biFrameGovernor % 2)){ //animate on even only. zapbotMesh1.position = points[index]; index = (index == points.length-1)?0:index+1; } }); Slowed it down ... and it does not approximate time well. Which is where Interpolation is good. Because it adds precise time....(ish). My brain still does not get interpolateAllThingsMethod() could someone explain? So ... necessity to use TWEEN. I like it. Can that not be taboo pls? Thx! Anyway we will see if it even works... Quote Link to comment Share on other sites More sharing options...
JackFalcon Posted December 12, 2017 Author Share Posted December 12, 2017 IT WORKED: /******************************RECURSIVE-TRACK-TWEEN****************************************/ // <!--TWEENJS--> // <script src="../../../lib/tweenjs/Tween.js"></script> // <script src="../../../lib/tweenjs/RequestAnimationFrame.js"></script> /**************************************-------------****************************************/ /******************************RECURSIVE-TRACK-TWEEN****************************************/ var trackIndex = 1; var pathTargetOrb = BABYLON.Mesh.CreateSphere("sphere", 14, 1, scene); pathTargetOrb.position= new BABYLON.Vector3(pathTargetOrb.position.x, pathTargetOrb.position.y, pathTargetOrb.position.z); var speedGovernor = 100; var recursiveTrackTween = function() { var targetPoint = points[trackIndex] var currentPoint = { x:pathTargetOrb.position.x, y: pathTargetOrb.position.y, z:pathTargetOrb.position.z }; var pathTween = new TWEEN.Tween( currentPoint ).to( { x: targetPoint.x, y: targetPoint.y, z:targetPoint.z }, speedGovernor ).onUpdate( function() { pathTargetOrb.position.x=this.x; pathTargetOrb.position.z=this.z; pathTargetOrb.position.y=this.y; }).onComplete(function() { trackIndex = (trackIndex < points.length-2) ? trackIndex+1 : 0; //loop the track. 3 magic number because extra nodes in infinity loop... recursiveTrackTween(); }); pathTween.start(); } recursiveTrackTween(); /******************************RECURSIVE-TRACK-TWEEN****************************************/ This makes for a buttery smooth 60fps orbit around the infinity symbol points[] curve path... at any speed --> just adjust the speedGovernor! aFalcon is terrible at playgrounds... sorry! Arte 1 Quote Link to comment Share on other sites More sharing options...
JackFalcon Posted December 12, 2017 Author Share Posted December 12, 2017 Hi @Arte that code above ... the EditNodes function... is what I've been (also) working on for you. There was a difference when applying to your playground... Above is for editing a Curve, also converted from Ribbon, but has not been applied to MeshBuilder (yet)... It is really fun (easy) to use... quad-state click-editor! Tons of potential! Sorry I seem to have problems with playgrounds. L8r. Quote Link to comment Share on other sites More sharing options...
Arte Posted December 12, 2017 Share Posted December 12, 2017 I’m keeping eye on it. JackFalcon 1 Quote Link to comment Share on other sites More sharing options...
JackFalcon Posted December 12, 2017 Author Share Posted December 12, 2017 Cool @Arte, I'll be back on that code in a few days... just shot out of an animation-cannon... will give you a ping... when something lands in the dirt! Arte 1 Quote Link to comment Share on other sites More sharing options...
MarianG Posted December 13, 2017 Share Posted December 13, 2017 11 hours ago, aFalcon said: aFalcon is terrible at playgrounds... sorry! But we love playgrounds https://www.babylonjs-playground.com/#3NYWX5#5 Arte and JackFalcon 2 Quote Link to comment Share on other sites More sharing options...
MarianG Posted December 13, 2017 Share Posted December 13, 2017 By the way @aFalcon, if you need direction too, take a lok here http://www.babylonjs-playground.com/#1YD970#14 JackFalcon 1 Quote Link to comment Share on other sites More sharing options...
JackFalcon Posted December 13, 2017 Author Share Posted December 13, 2017 Mr. G! @MarianG Yes I love playgrounds as well... Planning sprint of writing documentation with playground based tutorials. CURRENT-EXAMPLES (eventually for playground & doc): Fake-Physics of a character orbiting the Infinity Path (you helped with, thank you): #1 PATH-ORIENTATION, then #2 ROLL. PATH-ORIENTATION: SOLUTION: lookAt next index vertex in the path... var pathTargetOrb; var recursiveTrackTween; var createInfinityLoops = function(){ //track Gerono var points = []; for(var t = 0; t < 2 * Math.PI; t += Math.PI / 36) { scale = 80 / ( 3 - Math.cos(2 * t)); points.push(new BABYLON.Vector3(scale * Math.cos(t), 0, scale * Math.sin(2 * t)/2)); } points.push(points[0]); var trackG = BABYLON.MeshBuilder.CreateLines('trackG', {points: points}, scene); trackG.position.y = -1.2; //track Bernoulli var points = []; var pathSubdivisions = 180; // for(var t = 0; t < 2 * Math.PI; t += Math.PI / 36) { for(var t = 0; t < 2 * Math.PI; t += Math.PI / pathSubdivisions) { //subdivisions! less is faster more jumpy, more is slower and smoother. scale = 50 / ( 3 - Math.cos(2 * t)); points.push(new BABYLON.Vector3(scale * Math.cos(t), 3, scale * Math.sin(2 * t)/2)); } points.push(points[0]); var track = BABYLON.MeshBuilder.CreateLines('track', {points: points}, scene); var abox = BABYLON.Mesh.CreateBox("box", 6.0, scene); //SHOW-VERTICES-ON-PATH-. // showEditNodes(points,{type:'box', size:0.25}) /******************************RECURSIVE-TRACK-TWEEN****************************************/ var trackIndex = 1; pathTargetOrb = BABYLON.Mesh.CreateSphere("sphere", 14, 1, scene); pathTargetOrb.position= new BABYLON.Vector3(pathTargetOrb.position.x, pathTargetOrb.position.y, pathTargetOrb.position.z); var speedGovernor = 10; //this needs to be balanced with path-subdivisions - to get a smooth and fast speed! recursiveTrackTween = function() { //ANIMATE-ZAPBOT-. var zapTargetPoint = points[trackIndex] var zapCurrentPoint = { x:abox.position.x, y: abox.position.y, z:abox.position.z }; var pathTween = new TWEEN.Tween( zapCurrentPoint ).to( { x: zapTargetPoint.x, y: zapTargetPoint.y, z:zapTargetPoint.z }, speedGovernor ).onUpdate( function() { abox.position.x=this.x; abox.position.z=this.z; }).onComplete(function() { trackIndex = (trackIndex < points.length-2) ? trackIndex+1 : 0; //loop the track. 2 magic number because extra nodes in infinity loop... abox.lookAt(points[trackIndex+1]); //<--ORIENTATION: to PATH. recursiveTrackTween(); }); pathTween.start(); } /******************************RECURSIVE-TRACK-TWEEN****************************************/ } (playground eventual). Also --> this includes a neat optimization for SPEED STUDY: - 1) check out the first part named pathSubdivisions. It is how many vertices subdivide the entire symbol. This is important because: less is FASTER (but more jumpy around curve with on lookAt), and more subdivisions is SLOWER (and more smooth, turning corners)! - 2) the speed then can be adjusted to match the smoothness with the speedGovernor. #2 ROLL on curve (calculate angle among points...) QUESTION: What is the best way to detect angle on 3 points? RE-STATED: How to take 3 points from Infinity Path and detect if it is convex or concave? <looking> ... Quote Link to comment Share on other sites More sharing options...
JackFalcon Posted December 14, 2017 Author Share Posted December 14, 2017 #2 - How to Detect Convex and Concave on a Path? UPDATE: detecting angle was not enough because left angle was the same as right angle. Needed something different -> found this: Above is a clockwise test of the mathematical function. It might work... Quote Link to comment Share on other sites More sharing options...
JackFalcon Posted December 14, 2017 Author Share Posted December 14, 2017 SUCCESS! It worked... Detecting Motion Path Convex and Concave Curves and then adding ROLL rotation as the character Corners: /******************************RECURSIVE-MOTION-PATH-TWEEN****************************************/ var trackIndex = 1; pathTargetOrb = BABYLON.Mesh.CreateSphere("sphere", 14, 1, scene); pathTargetOrb.position= new BABYLON.Vector3(pathTargetOrb.position.x, pathTargetOrb.position.y, pathTargetOrb.position.z); var speedGovernor = 10; //this needs to be balanced with path-subdivisions - to get a smooth and fast speed! recursiveTrackTween = function() { //ANIMATE-ZAPBOT-. var zapTargetPoint = points[trackIndex] var zapCurrentPoint = { x:zapbotMesh1.position.x, y: zapbotMesh1.position.y, z:zapbotMesh1.position.z }; var pathTween = new TWEEN.Tween( zapCurrentPoint ).to( { x: zapTargetPoint.x, y: zapTargetPoint.y, z:zapTargetPoint.z }, speedGovernor ).onUpdate( function() { zapbotMesh1.position.x=this.x; zapbotMesh1.position.z=this.z; }).onComplete(function() { trackIndex = (trackIndex < points.length-2) ? trackIndex+1 : 0; //loop the track. 2 magic number because extra nodes in infinity loop... //ORIENTATION: to PATH. zapbotMesh1.lookAt(points[trackIndex+1]); //ROLL: tilt cornering. var tilt = convexConcave(points[trackIndex],points[trackIndex+1]) if(tilt < 3.14 && tilt > 3.130){ //Right turn. zapbotMesh1.rotation.z = 0.1; } else if (tilt < 3.130 && tilt > 2){ //Right turn. zapbotMesh1.rotation.z = 0.2; } else if (tilt > -3.14 && tilt < -3.130){ //Left turn. zapbotMesh1.rotation.z = -0.1; } else if (tilt > -3.130 && tilt < -2){ //Left turn. zapbotMesh1.rotation.z = -0.2; } else { zapbotMesh1.rotation.z = 0; } recursiveTrackTween(); }); pathTween.start(); } /******************************RECURSIVE-MOTION-PATH-TWEEN****************************************/ // convex > 0, concave < 0, backward = 0, fwd = -3.14 function convexConcave (nextV, currentV) { return ((Math.atan2(nextV.x, nextV.z) - Math.atan2(currentV.x, currentV.z) + Math.PI * 2) % (Math.PI * 2)) - Math.PI; } The convexConcave method detects which way the character is turning, and applies (gradual) ROLL rotation. MarianG 1 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.