Jump to content

Actions and Buttons


SethRing
 Share

Recommended Posts

Hi,

 

Posting for the first time in a new forum is always slightly scary, but you all seem very kind. Hopefully that holds true  ;)

 

My question is about Actions and Buttons. I've been able to create an action based on interaction with a mesh, but I'm wondering if there is an easy way to hook an action and a button so that the action triggers on a button push. I'm figuring there has to be since joshcamas does it in his nifty SamacEditor

 

Can someone point me to some documentation on this issue? Thanks.

Link to comment
Share on other sites

Hi,

 

The actions are triggered in Babylon from a trigger on a 3D object. The shares can not be triggered from a html button. You can optionally create a 3d button that will trigger actions, but if your button is on top of the canvas you can not use the actions.

Link to comment
Share on other sites

Welcome to the forums!

 

I do not actually use the action manager, funnily enough. I basically do what Paradine showed - run a function on the "onclick" event. :D

 

You can do this in many ways, including:

 

HTML:

<button type="button" onclick="runFunction('hello')">Click Me!</button>

OR

 

Javascript: (Paradine's Method)

var coolButton = document.getElementById("sweetButton");coolButton.onclick = function () {    alert("Chicken Sauce!");}

or you can even use jquery. No need for the actionmanager. :D

Link to comment
Share on other sites

Thank you all for your responses!

 

I must be missing something because I tried the button/function method before my first post and couldn't get it to work. My code is as follows:

<button type="button" onclick="showTop('T115')">Round</button><button type="button" onclick="showTop('T345')">Rectangular</button>
<script>    if (BABYLON.Engine.isSupported()) {        var canvas = document.getElementById("renderCanvas");        var engine = new BABYLON.Engine(canvas, true);                BABYLON.SceneLoader.Load("", "test.babylon", engine, function (newScene) {          var meshT115 = newScene.getMeshByName("T115").visibility = 0;          var mesh510 = newScene.getMeshByName("510").visibility = 0;          var meshT345 = newScene.getMeshByName("T345").visibility = 1;          var mesh350 = newScene.getMeshByName("350").visibility = 0;          var myBaseMesh = newScene.getMeshByName("510");          var materialMyMesh = new BABYLON.StandardMaterial("texture1", newScene);          materialMyMesh.diffuseTexture = new BABYLON.Texture("assets/images/stain/Natural.jpg", newScene);          materialMyMesh.specularPower = 50;          myBaseMesh.material = materialMyMesh;          var myTopMesh = newScene.getMeshByName("T345");          var materialMyMesh = new BABYLON.StandardMaterial("texture2", newScene);          materialMyMesh.diffuseTexture = new BABYLON.Texture("assets/images/stain/Natural.jpg", newScene);          materialMyMesh.specularPower = 50;          myTopMesh.material = materialMyMesh;            // Wait for textures and shaders to be ready            newScene.executeWhenReady(function () {                // Attach camera to canvas inputs                var myCamera = new BABYLON.ArcRotateCamera("ArcRotateCamera", 1, 0.8, 5, new BABYLON.Vector3(0, 0, 0), newScene);                var light0 = new BABYLON.HemisphericLight("Hemi0", new BABYLON.Vector3(.1, .1, .1), newScene);                light0.diffuse = new BABYLON.Color3(.1, .1, .1);                light0.specular = new BABYLON.Color3(.1, .1, .1);                light0.groundColor = new BABYLON.Color3(.5, .5, .5);                newScene.activeCamera = myCamera;                newScene.activeCamera.attachControl(canvas);                // Once the scene is loaded, just register a render loop to render it                engine.runRenderLoop(function() {                    newScene.render();                });            });        }, function (progress) {            // To do: give progress feedback to user        });    }      function showTop(x) {    newScene.getMeshById("myTopMesh").visibility = 0;    newScene.getMeshById(x).visibility = 1;  }</script> 

I manually grab my 4 meshes and set their visibility (hiding all but T345). I then try to call my showTop() function to hide the current top mesh (myTopMesh) and display the submitted mesh.

What am I missing?

Link to comment
Share on other sites

You can create a global variable:  var myNewScene = null;

 

BABYLON.SceneLoader.Load("", "test.babylon", engine, function (newScene) {

    myNewScene  = newScene;

    ---

 

Error

and use it in your function signature showTop: 

 

function showTop(x, myScene) {

    myScene.getMeshById("myTopMesh").visibility = 0;
    myScene.getMeshById(x).visibility = 1;
}

 

<button type="button" onclick="showTop('T115', myNewScene)">Round</button>

...

 

see fixed bottom

Link to comment
Share on other sites

I tried adding the global but I get the following error:

Uncaught TypeError: undefined is not a function showTop onclick

I feel like I'm missing something really simple. With how easy babylon.js has been to use so far I can't believe that there isn't a simple solution to this that I'm just not getting.

Thanks for all your help so far.

Link to comment
Share on other sites

Try to use the global variable directly once assign rather than using it in the signature.

 

 it was a error to use myNewScene it in the signature. Sorry.

 



var myNewScene = null;

BABYLON.SceneLoader.Load("", "test.babylon", engine, function (newScene) {
myNewScene = newScene;
---

function showTop(x) {
myNewScene.getMeshById("myTopMesh").visibility = 0;
myNewScene .getMeshById(x).visibility = 1;
}

<button type="button" onclick="showTop('T115')">Round</button>


Link to comment
Share on other sites

Hi.  In certain circumstances, putting 'window' in front.... brings things back in scope.

ie. 

window.showTop = function(x) { ... }

   or

function window.showTop(x) { ... }

*shrug*  Deltakosh and Dad72 taught me about named functions and anonymous functions... here: http://www.html5gamedevs.com/topic/2571-the-wingnut-chronicles/page-17#entry46784  (and the post after that one, too).  Maybe something there can help.

The dynamic html 'hide editor' and 'show editor' buttons here... http://playground.babylonjs.com/#YIT1S ...use functions like that (way at the bottom).  Something similar might work for you, too.  It's not necessarily the best practice, because it puts the functions on the window object, which is global, so it can collide with other browser functions.

"seth ring" as in Jane Robert's "Seth"?  I'm a big fan.  Maybe we'll talk some more, later, in the back channels.  Feel free to PM me about it, if you want to.  Rumor has it that we create our own (virtual) reality.  ;)  (a good framework helps)

Link to comment
Share on other sites

I think this is time to bring up that I added an append() method to SceneLoader a while back.  The purpose then was for ease of loading more than one .babylon, and not just meshes.  With append(), you pass the scene, so it is already instanced by you.  Slightly more elegant than putting a copy out to a "reference global" in a loader call back.  see http://www.html5gamedevs.com/topic/8346-does-sceneloaderimportmesh-import-lights-and-cameras/ for more, start page 2 I think.

Link to comment
Share on other sites

I usually create the button itself when babylon is supported and show it only when scene is loaded. If the button is used only with babylon.
 

if (BABYLON.Engine.isSupported()) {      var btnLegend = document.createElement("button");      btnLegend.id = "showLegend";      btnLegend.textContent = "Legend";      btnLegend.hidden = true;      document.getElementById("someDivId").appendChild(btnLegend);      //.....      var scene = createScene();      var executedWhenReady = function (){           btnLegend.onclick = function (btn) {                 //DoSth           };           btnLegend.hidden = false;      };      scene.executeWhenReady(executedWhenReady);}
Link to comment
Share on other sites

Xeonzinc, I've been trying to do the whole DOM button thing but I'm apparently not smart enough to figure it out. Anyone feel like taking a look at my code?

<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head>    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>    <title>Babylon - Basic scene</title>    <link rel="stylesheet" type="text/css" href="assets/css/style.css">    <script type="text/javascript" src="//use.typekit.net/ilr4lzl.js"></script>    <script type="text/javascript">try{Typekit.load();}catch(e){}</script>    <script src="assets/js/babylon.js"></script>    <script src="assets/js/hand-1.3.8.js"></script>    <script src="assets/js/cannon.js"></script>  <!-- optional physics engine --></head><body>	<div id="container">		<!-- Page Content -->		<div id="content">      <div id="tableBuilder">        <div id='cssmenu'>          <ul id="tops">            <button type="button" onclick="showTop('T115')">Round</button>            <button type="button" onclick="showTop('T345')">Rectangular</button>          </ul>        </div>			  <canvas id="renderCanvas"></canvas>      </div>    </div>  </div>  <script>    if (BABYLON.Engine.isSupported()) {      var myNewScene = null;      var canvas = document.getElementById("renderCanvas");      var engine = new BABYLON.Engine(canvas, true);            BABYLON.SceneLoader.Load("", "test.babylon", engine, function (newScene) {        myNewScene = newScene;        var meshT115 = newScene.getMeshByName("T115").visibility = 0;        var mesh510 = newScene.getMeshByName("510").visibility = 1;        var meshT345 = newScene.getMeshByName("T345").visibility = 1;        var mesh350 = newScene.getMeshByName("350").visibility = 0;        var myBaseMesh = newScene.getMeshByName("510");        var materialMyMesh = new BABYLON.StandardMaterial("texture1", newScene);        materialMyMesh.diffuseTexture = new BABYLON.Texture("assets/images/stain/Natural.jpg", newScene);        materialMyMesh.specularPower = 50;        myBaseMesh.material = materialMyMesh;        var myTopMesh = newScene.getMeshByName("T345");        var materialMyMesh = new BABYLON.StandardMaterial("texture2", newScene);        materialMyMesh.diffuseTexture = new BABYLON.Texture("assets/images/stain/Natural.jpg", newScene);        materialMyMesh.specularPower = 50;        myTopMesh.material = materialMyMesh;        // Wait for textures and shaders to be ready        newScene.executeWhenReady(function () {          // Attach camera to canvas inputs          var myCamera = new BABYLON.ArcRotateCamera("ArcRotateCamera", 1.2, 1.2, 5, new BABYLON.Vector3(0, 0.1, 0.1), newScene);            var light0 = new BABYLON.HemisphericLight("Hemi0", new BABYLON.Vector3(0, 50, 0), newScene);          light0.diffuse = new BABYLON.Color3(.2, .2, .2);          light0.groundColor = new BABYLON.Color3(.5, .5, .5);          newScene.activeCamera = myCamera;          newScene.activeCamera.attachControl(canvas);          // Once the scene is loaded, just register a render loop to render it          engine.runRenderLoop(function() {              newScene.render();          });        });      }, function (progress) {          // To do: give progress feedback to user      });    }    function showTop (x) {        myNewScene.getMeshById("myTopMesh").visibility = 0;        myNewScene.getMeshById(x).visibility = 1;    }    </script></body></html>

So far I've gotten it to load, display my scene and then do nothing.

 

Each time I hit a button it gives me that "Uncaught TypeError: undefined is not a function" error on line 83. Which confuses me since I don't understand why the browser thinks "myNewScene.getMeshById("myTopMesh").visibility = 0;" should be a function...

Sorry for the totally beginner questions.

Link to comment
Share on other sites

No need to apologize at all, Sethring.  We enjoy having you with us, no matter what your skill levels, and don't sell yourself short.  Your code is looking pretty good.  Do you see how function showTop is sort of isolated from the other code?  Even though it is inside the same script element as the...

if (BABYLON.Engine.isSupported()) { ... }

...it is not within its braces.  And inside its braces is where you did...

myNewScene = newScene;

Just maybe...  'myNewScene' is 'undefined' as far as function showTop is concerned.  If you add...

alert(myNewScene);

...as the first line of the showTop function, and run it... (and click your showTop button)... I bet the alert would report 'undefined' or maybe a giant nothing.  ;)

 

I am not a very good JS coder... but maybe... maybe... if you moved this line...

var myNewScene = null;

...one line higher (above the 'if' line), then maybe your new alert would start reporting 'object' (a good thing).  With this move, maybe myNewScene would become more global (maybe).

 

And if THAT doesn't work, I have another idea.  Maybe make THIS line...

var myNewScene = engine.scenes[0];

...be the first line of showTop function.  We will make myNewScene become 'defined' (for showTop) even if we have to 'lookup' the scene via the global 'engine' object (even if it kills us).  :) 

 

That's a couple things that you can try.  No promises.  The showTop function looks mighty lonely and isolated.  Maybe it hasn't heard the news about myNewScene getting defined.  Once you put that alert line as the first line of showTop function, you will know the facts about that. 

 

alert() and console.log() are our friends.  They can report 'the situation' at various places in the code.  But you know all that, already.   Good luck!

Link to comment
Share on other sites

Try this directly as you suggest Wingnut. This way has a fail-safe

function showTop (x) {    myNewScene = myNewScene || engine.scenes[0]; //myNewScene be assigned by the variable already assigned or is going search of scene in the engine.    myNewScene.getMeshById("myTopMesh").visibility = 0;    myNewScene.getMeshById(x).visibility = 1;} 
Link to comment
Share on other sites

  • 2 weeks later...

See your posting of approaching this in a different way.  Thought I would give an example of SceneLoader.Append.  Note that scene is at script tag scope.  It is assigned directly by a call to the constructor.  Your code in showTop() may not work, but maybe you need to break up your getMesh call into a separate line from assigning visibility, to make sure it is returning a mesh first.

var scene;if (BABYLON.Engine.isSupported()) {    var canvas = document.getElementById("renderCanvas");    var engine = new BABYLON.Engine(canvas, true);    scene = new BABYLON.Scene(engine);    BABYLON.SceneLoader.Append("", "test.babylon", scene, function (newScene){ ... });}function showTop(x) {  scene.getMeshById(x).visibility = true;  }
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...