dabrorius Posted August 31, 2014 Share Posted August 31, 2014 Hi,I'm trying to load a photo as a texture on to a piece of a (square) mesh. The problem is that original photo is not square so I need to somehow figure out aspect ratio of it so I can modify the mesh to fit it. What's the best way to do it? I can fetch the image via url using pure JS but that does not seem right and introduces some problems because that request is asynchronous. Any suggestion? Quote Link to comment Share on other sites More sharing options...
Wingnut Posted September 1, 2014 Share Posted September 1, 2014 Hi dabrorius... welcome to the forum. I am not an expert on this at all... but... I have an idea. I am going to assume that you do not know what the dimensions of the picture are, and you would like to use Babylon.js to help ascertain the picture size, so you can make a plane/rectangle which has the same proportions as the image. First, in our Playpen Tutorials, take note of the Materials tutorial and the Discover Basic Elements tutorial. In basic elements, in the "Grounds' section, you will find the command CreateGround. It just makes a plane (square) that you can easily set width and height upon. We won't make one yet, but just keep that in mind. Now, in the Materials tutorial, you will find this line... materialSphere1.diffuseTexture = new BABYLON.Texture("grass.png", scene); Lets change that line to...var mypicture = new BABYLON.Texture("picture_url", scene); // rem about CORS rules for cross-domainAdjust 'picture_url' to a working picture URL, of course. Now you've got a variable (mypicture) that is the picture (if the load was successful). Next, look at the API for the BABYLON.Texture class object... http://doc.babylonjs.com/page.php?p=24708 . Scroll down until you see the .getSize() method. "Return the size of the texture in an array" So... maybe next you can try...var sizearray = mypicture.getSize();console.log(sizearray); // examine the array's format & compare values to test pic sizes.Let's pretend the sizearray returns: [1024, 768] I bet you know what's coming next. That's right... our friend the ground plane (from basic elements) and its material.var ground = BABYLON.Mesh.CreateGround("gnd", sizearray[0]/100, sizearray[1]/100, 1, scene);That makes a plane that is 10.24 (units) wide and 7.68 (units) deep/high (because we divided both values by 100). Note: You are not 'required' to divide by 100. You could make the ground plane be 1024 units wide and 768 units high... if you prefer. Or divide by 10, so the ground plane is 102.4 units by 76.8 units. Just place the camera far enough away from the picture so that you can see it completely. Continue with applying the picture to the ground plane? Ok. Now you create a new BABYLON StandardMaterial for the ground, and apply it...var gndmat = new BABYLON.StandardMaterial("gmat", scene);ground.material = gndmat;Now that you have a standard material applied on the ground, make the picture be its diffuseTexture...gndmat.diffuseTexture = mypicture;In theory, you are done... if I understand the issue correctly. Summary: - Make a babylon texture-class object that does an image load - Call the getSize() function on it... to get its size (into an array) - Use the values in that array (divided by identical values - we used 100)... to make a ground plane (that is proportionally identical to the picture, ratio-wise). Disclaimer: I could be completely wrong and/or be misunderstanding. I'm not responsible for any computer damage caused by using this idea. hehe. There are VERY smart people here who will likely have more and better ideas. I am not very experienced on this subject AT ALL. You have been warned, dabrorius. Again, welcome to the forum! Keep us posted on your progress and discoveries, and troubles... if you have some. Quote Link to comment Share on other sites More sharing options...
dabrorius Posted September 1, 2014 Author Share Posted September 1, 2014 Hi Wingnut Thanks a lot for a very detailed explanation, I actually understood most of the stuff already but I just missed the getSize() method.Now the only problem left is that if I call getSize() immediately after creating the texture I get width and height 0. I guess that's because image wasn't loaded yet. Is there's some kind of callback method that I can pass, for example "onTextureLoad" or something? Quote Link to comment Share on other sites More sharing options...
Wingnut Posted September 1, 2014 Share Posted September 1, 2014 Ahh, good, you are not quite as newbie as you COULD have been. (I never know how experienced the person is, so I over-explain sometimes... sorry.) Read further past the getSize() method. See the isReady() method? Again, I don't promise that it works... I've never used it. But it's worth a try. Quote Link to comment Share on other sites More sharing options...
RaananW Posted September 1, 2014 Share Posted September 1, 2014 Hi dabrorius, I believe you can leave the plane as you wanted it, and simply change the uScale and vScale of the texture.Made a small example, I hope this is what you meant : http://www.babylonjs.com/playground/#2JUBQI The only downside of wingnut's suggestion (which i believe would work) is that the object will then have to be proportional to the image. Quote Link to comment Share on other sites More sharing options...
Wingnut Posted September 1, 2014 Share Posted September 1, 2014 Good point, raananw. Maybe I misunderstood... but I thought dabrorius wanted to make the mesh fit the picture, and not make the picture fit the mesh. *shrug* That's why the method I used... measured the picture first, and then created the mesh. But dabrorius, raananw is absolutely correct. By scaling the picture, you can make it fit any planar mesh. But... you will be changing the picture's aspect ratio, unless you use identical values for uScale and vScale. Quote Link to comment Share on other sites More sharing options...
dabrorius Posted September 1, 2014 Author Share Posted September 1, 2014 Ahh, good, you are not quite as newbie as you COULD have been. (I never know how experienced the person is, so I over-explain sometimes... sorry.) Read further past the getSize() method. See the isReady() method? Again, I don't promise that it works... I've never used it. But it's worth a try. Well isReady() method is ok but then I have to poll it every X milliseconds and check if it has loaded, I would expect there to be a callback function since it's javascript after all. Hi dabrorius, I believe you can leave the plane as you wanted it, and simply change the uScale and vScale of the texture.Made a small example, I hope this is what you meant : http://www.babylonjs.com/playground/#2JUBQI The only downside of wingnut's suggestion (which i believe would work) is that the object will then have to be proportional to the image. Well this is also an option for sure, but I'm just troubled by finding the width/height of the image currently. Quote Link to comment Share on other sites More sharing options...
Temechon Posted September 1, 2014 Share Posted September 1, 2014 Hey there, Well isReady() method is ok but then I have to poll it every X milliseconds and check if it has loaded, I would expect there to be a callback function since it's javascript after all. Well this is also an option for sure, but I'm just troubled by finding the width/height of the image currently. scene.executeWhenReady is available here Cheers, Quote Link to comment Share on other sites More sharing options...
dabrorius Posted September 1, 2014 Author Share Posted September 1, 2014 Hey there, scene.executeWhenReady is available here Cheers, Thanks, that worked! But, I just noticed that getSize() on texture does not return size of an image, it returns size of a texture which is always a power of two (512x512, 512x1024 etc.) Quote Link to comment Share on other sites More sharing options...
Wingnut Posted September 1, 2014 Share Posted September 1, 2014 Huh, thanks for the info on that, dabs. Sorry I sent you down the wrong path. Maybe a stock JS solution would be able to gather the dimensions... such as http://stackoverflow.com/questions/106828/javascript-get-image-height/952185 ? Cool challenge. Quote Link to comment Share on other sites More sharing options...
dabrorius Posted September 1, 2014 Author Share Posted September 1, 2014 I just used pure JS in the end. Thanks everybody. Here's the code if anyone finds this topic later.var img = new Image();img.onload = function() { alert(this.width + 'x' + this.height);}img.src = 'http://www.google.com/intl/en_ALL/images/logo.gif'; Quote Link to comment Share on other sites More sharing options...
andrew_ Posted August 28, 2015 Share Posted August 28, 2015 Thank you everyone for all of the above.... So in order to create a plane with the same aspect ratio as an image, I actually have to create a "ground" ?I mean if I create a regular type of BABYLON.plane - it appears that it can only ever be square? What I'm trying to do is create a click button that "hangs in space" ... it is a rectangular button - I already got the graphic. My first thought was use a sprite, which worked perfectly in terms of the graphic, but seems to come a cropper if you want it to respond to mouse-over.So then I figured I would use a plane, but this seems to have aspect ratio problems.The problem with using "Ground" in the first instance is that I'm going to have to rotate it. As a newbie, I'm thinking there has got to be an easy way to do this, and I just don't know what it is. Big thanks for help. Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted August 28, 2015 Share Posted August 28, 2015 Beware: Babylon.Plane is a math structure and not a mesh andrew_ 1 Quote Link to comment Share on other sites More sharing options...
andrew_ Posted August 29, 2015 Share Posted August 29, 2015 Ok, but BABYLON.Mesh.CreatePlane creates a planar Mesh structure, right? ... But one of my EWWBLs is that it will only create a square mesh.I suppose if I made the PNG into a square with whatever part of it transparent, that would stop the problem of the material getting stretched in one of the dimensions. But then mousing over the transparent portion would register as a mouse-over event which would be wrong. 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.