JohnK Posted October 6, 2015 Share Posted October 6, 2015 This is probably one for @Jerome but others will have more idea than I do anyway. Have been playing with the Rhombicuboctahedron and trying to place the same image on each face. (Starting with one image rather than an image atlas as thought it would be easier). Pinching bits and pieces from here and there from BABYLON.js max I created this playground. As you can see I got in a bit of a mess - something to do with having the uvs in the wrong order probably. Any help gratefully received. Jerome should you want to answer this one then I know you have a long backlog of things to do so no rush - just interested nothing vital. Quote Link to comment Share on other sites More sharing options...
jerome Posted October 6, 2015 Share Posted October 6, 2015 WellThis polyhedron has different polygonal shapes for faces (triangles and squares, if I'm not wrong), so you can't have only one "rule" (ie uvs declaration) working for all these polygons.Moreover you had to convert the mesh to a flat shaded one, what is a good thing to add vertices (*) if you want the same image on each face (it can't really be the same as we have squares and triangles !) and this conversion applied after you set the uvs. I guess the new vertices don't hold any uvs at all. (*) you can't "copy" the same image on different faces if the vertices are common to several faces.1 vertex <=> 1 uv So if the vertex belongs to 2 facets, it can't hold the image coordinates for facet1 and the image coordinates for facet2 in the same time. It's really hard to do.You would have to :- define the uvs for the facet composing a triangle- define the uvs for the pair of facets composing a square- iterate on every vertex and guessing if it is a part of a triangle or a square (to choose what definition to use) and where it is on the square or the triangle http://www.babylonjs-playground.com/#1H7L5C#1 Quote Link to comment Share on other sites More sharing options...
JohnK Posted October 7, 2015 Author Share Posted October 7, 2015 @Jerome in my simple minded way I thought I had some of the points you mentioned covered, though obviously not because it didn't work. I'll describe my thinking and perhaps if you have time you could pinpoint my errors and then I can have another go. I did try to deal with the fact that there are triangular and square faces and expected the triangular ones possibly not to work but was going to deal with that later provided the square faces worked (but didn't). I looked at your Babylon.js/src/Mesh/babylon.mesh.vertexData.ts file and saw on lines 6387 to 657 that for each face a uv pair was pushed for each vertex of the face. So with one image my Vector4 of uvs would be [0,0,1,1] equivalent to you faceUV[index] with index always 0. So in the playground I set up my uv pairs as (line 33)var face_uvs=[[0,0],[1,0],[1,1],[0,1]];then in lines 42 - 44 for each of the faces in the Rhombicuboctahedron the length of data.face[f] gives the number of vertices sofor(var j = 0; j < data.face[f].length; j++) { uvs=uvs.concat(face_uvs[j]);}pushes a uv pair in order to uvs -- uvs=uvs.concat(face_uvs[j]) being I hope the same as uvs.push(face_uvs[j][0],face_uvs[j][1]) This appears to set the uv for each vertex of each face whether the face has 3 sides or 4 sides As much as I want it to and it looks like it should it obviously does not cover your points 1 vertex <=> 1 uv - define the uvs for the facet composing a triangle- define the uvs for the pair of facets composing a square- iterate on every vertex and guessing if it is a part of a triangle or a square (to choose what definition to use) and where it is on the square or the triangle What is wrong with my reasoning? Does either of BABYLON.VertexData.ComputeNormals or BABYLON.VertexData._ComputeSides change the order in which vertices are considered and so throw out the match I created between face vertices and the uvs? Am I just completely wrong? Quote Link to comment Share on other sites More sharing options...
jerome Posted October 7, 2015 Share Posted October 7, 2015 computeNormals only sets the normals arraycomputeSides can change the number of vertices (so the number of indices and uvs also) and/or the indices order... unless if you choose FRONTSIDE or DEFAULTSIDE : these don't change anything. So for your case, you can forget these two functions, they don't modify anything. convertToFlatShaded can/will add vertices to your geometry !So you set uvs to the initial polyhedron vertices and then add new ones. The problem is that we don't know where they are added unless we hack this method seriously. Let's imagine we don't use it now. As I can remember the array data.face is filled with the indices of the i-th facet, so 3 vertices per array. This means you should assign 3 pairs of uvs par data.face, not 4.This is the principle : a UV pair per vertex onlyNote well you won't achieve the goal you want because we have here quite all vertices that are common to many faces. (not easy to explain this in english for me, sorry) It was easy for me to set the uvs on a box because a box has exactly 6 similar faces in term of geometry (2 facets by face, always ordered the same known way) and no vertex was common to two different box faces.In short : I knew the geometry and the faces were all independant. It's really hard to do with these polyhedrons if you want the same image on each face. We should first make sure that each facet doesn't share its vertice with another one (what convertToFladShaded seems to do), else impossible to apply the same image on each face.Then we should understand the geometry : where are the vertices of each face, in this face : the ones related to the others. No way to set correct uvs without this piece of information.Finally we would code the algo to assign the right uvs to the right vertices regarding the former two points. I guess it's easier to fold an image around the whole polyhedron Quote Link to comment Share on other sites More sharing options...
dbawel Posted October 7, 2015 Share Posted October 7, 2015 Hi John K, I didn't thoroughly read every line in this post, but I get the gest of what you're trying to do. If it were me, I might try using multi materials, as you will be able to assign a different material to each set of UVs representing a face on your Rhombicuboctahedron. And this could be done proceedurally so that a different material is automatically pushed to the UVs which define each face on the mesh limiting (optimizing) the amount of lines of code required. But are you simply trying to torture yourself, or do you actually have a scene in mind where this might be used. For me, it would be a method of torture. It almost is just thinking about it. DB Quote Link to comment Share on other sites More sharing options...
JohnK Posted October 8, 2015 Author Share Posted October 8, 2015 DB as a retired maths teacher occasionally I like to give my maths brain a workout - torture for some pleasure for others, currently this is a mixture of both. Quote Link to comment Share on other sites More sharing options...
dbawel Posted October 8, 2015 Share Posted October 8, 2015 Check out this blog 9tutorial) written by DeltaKosh on applying Multi-Materials. You might find this useful. http://blogs.msdn.com/b/eternalcoding/archive/2013/07/10/babylon-js-using-multi-materials.aspx DB Quote Link to comment Share on other sites More sharing options...
JohnK Posted October 8, 2015 Author Share Posted October 8, 2015 DB I just like the way Jerome applied texture in the new Createxxx method applied to CreateBox. Will get round to multi-materials when I am exhausted from this method. Thank you for the support. @Jerome understanding is growing. I used the playground to create two Cubes, one uses your CreatePolyhedron method and one the new CreateBox method. Checking the VertexData for both shows the difference. In the CreateBox method there are 24 positions and 24 normals, since each of the 8 vertices is listed 3 times; once for each face it belongs to and each of the 6 normals (one per face) is listed 4 times once for each vertex on that face. The UVs are also listed 24 times each one matched in 1-1 correspondence with the positions. In the CreatePolyhedron method there are 8 positions and 8 normals one for each of the 8 vertices. The normals are now not normal to a face but are formed from the 3 face normals at each vertex. This method of storing the VertexData is more efficient since it uses a third less memory but does not contain sufficient data for the uvs to be applied. http://www.babylonjs-playground.com/#1H7L5C#29 shows the two cubes and the normals at the vertices. The lower one is made using the CreateBox method and all faces contain the image in a proper way. Interestingly the use of .convertToFlatShadedMesh(); produces 36 positions since it creates two facets per face and then 4 vertices belong to 6 facets and 4 vertices belong to 4 facets and there are 36 normals. The UV array also has 36 entries but I presume they do not now match correctly the positions. Remove the comment from line 70 in the playground above and see the difference. So perhaps if I can just work out which uv goes with which position I might get somewhere. Quote Link to comment Share on other sites More sharing options...
jerome Posted October 8, 2015 Share Posted October 8, 2015 Waaoww... When I said it was hard for me to explain all of this in english !You found out everything I wanted to tell you by yourself Very good study ! So you understand now why you can't reproduce the same image on each box side if its vertices belong to many faces at the same time.And why you can't set all the UV at mesh creation if you convert it to a flat shaded one just after (vertices added after). Actually, you need to have these extra vertices to hold the image-per-face uvs.So, two options :#1 : you create the mesh as you did formerly, you convert it to a flat shaded one, then you try to retrieve all the new vertices and how they are related in order to the initial to set the UVs. Not that simple.#2 : you change the way the mesh is created : instead of re-using some vertices, you add new ones when building the positions and indices array.In this case, you know exactly where all your vertices are and how they are linked.And it's quite easy to do : when a vertex is yet used in the faces array, just create a new one with the same values and reference it instead.In brief, to construct the geometry of each polyhedron like the current BJS box. I personally prefer the second method.I think I will implement it in the future CreatePolyhedron method because the way the normals are computed with computeNormals() on common vertices will get to many light artifacts on these kinds of meshes : many edges, many vertices, many flat planar sides, angles lower than 120° ... so many bad candidates for the magic normal computation.That's also why I converted all of them into flat shaded ones in the PG example. Quote Link to comment Share on other sites More sharing options...
JohnK Posted October 10, 2015 Author Share Posted October 10, 2015 Managed it at last. Rhombicuboctahedron with one image used on each face http://www.babylonjs-playground.com/#1H7L5C#13 Rhombicuboctahedron with spriteatlas and one sprite used per face http://www.babylonjs-playground.com/#1H7L5C#12 Wingnut and jerome 2 Quote Link to comment Share on other sites More sharing options...
jerome Posted October 10, 2015 Share Posted October 10, 2015 Waaaaowww Excellent work. I guess you did (so fast) what I intended to do for the upcoming CreatePolyhedron() method. Congratulations ! really really good work. Quote Link to comment Share on other sites More sharing options...
JohnK Posted October 10, 2015 Author Share Posted October 10, 2015 Still needs some work will fail if any polyhedra has a face with more than 4 sides and faceUV not consistent with yours, is array of array not array of Vector4. So still some way to go for a general CreatePolyhedron Quote Link to comment Share on other sites More sharing options...
jerome Posted October 11, 2015 Share Posted October 11, 2015 I had a look at your code.So you don't re-use the vertices and create new positions what is, imho, the right thing to do. I can see also that you compute your own normals and check on what plane side they should be set for each facet. Usually, the vertices are rightly ordered in the face array by the developer to create all the facets oriented the same way, so this check isn't necessary. Maybe it's not the case with this JSON file... I don't know.If they are, you don't need to reimplement your own normal computation in this case, ComputeNormals() will do the job as expected because you only create independant planar polygons. Your algo may work with any polyhedrons imho for the positions/indices aspect. I would have done the same, with ComputeNormals() so far. For the UV per side, my lead is :A texture is a rectangle, ok ? or a square... it is to say a 4-side polygonThe sides of a polyhedron are polygons. We can even assume they are quite regular polygons :triangles, rectangles/squares, pentagons, hexagons, etc So except for a triangle or a rectangle polygon (polyhedron sides) which can directly fit into a rectangle texture, I would consider the circle within the square texture and set the (face) polygon on this circle (circumcircle) to compute the UV.Not easy to explain in english once more ...But have a look please at how the UVs are set in CreateDisc() (this is actually a createPolygon) : https://github.com/BabylonJS/Babylon.js/blob/master/src/Mesh/babylon.mesh.vertexData.ts#L1288 Quote Link to comment Share on other sites More sharing options...
jerome Posted October 11, 2015 Share Posted October 11, 2015 I guess I will try next week to implement in BJS something like :CreatePolyhedron(name, {type: polyhedronType, size: number, custom: polygonObject}, scene);polyhedronType will be one of the few polyhedrons provided in the core. Few only (tatrehedrons, etc) because we don't want too much code in the core.If polyhedronType is undefined, then a custom polyhedron object will be expected. These objects will be provided in an extension library, easy to use : just copy/paste the needed variable in your code.Example :copy this line from the lib your code :var cubo = {"name":"Cuboctahedron","category":["Archimedean Solid"],"vertex":[[0,0,1.154701],[1,0,0.5773503],[0.3333333,0.942809,0.5773503],[-1,0,0.5773503],[-0.3333333,-0.942809,0.5773503],[1,0,-0.5773503],[0.6666667,-0.942809,0],[-0.6666667,0.942809,0],[0.3333333,0.942809,-0.5773503],[-1,0,-0.5773503],[-0.3333333,-0.942809,-0.5773503],[0,0,-1.154701]],"edge":[[0,1],[1,2],[2,0],[0,3],[3,4],[4,0],[1,6],[6,5],[5,1],[2,8],[8,7],[7,2],[3,7],[7,9],[9,3],[4,10],[10,6],[6,4],[5,11],[11,8],[8,5],[9,11],[11,10],[10,9]],"face":[[0,1,2],[0,3,4],[1,6,5],[2,8,7],[3,7,9],[4,10,6],[5,11,8],[9,11,10],[0,2,7,3],[0,4,6,1],[1,5,8,2],[3,9,10,4],[5,6,10,11],[7,8,11,9]]};then :CreatePolyhedron(name, {custom: cubo}, scene); Quote Link to comment Share on other sites More sharing options...
JohnK Posted October 11, 2015 Author Share Posted October 11, 2015 Thanks for you advice, have replaced my normals code with computeNormals. In the end I did not use the CreateDisc idea for the uvs since I needed to find the middle for each face and it gave one more position per face. My triangles for the uvs all start from one vertex of the polygon face and go to the non-adjacent ones in turn. Having calculated the first vertex I rotate this round the polygon to get the positions of the others and then translate and scale. Results http://www.babylonjs-playground.com/#1H7L5C#18 http://www.babylonjs-playground.com/#21QRSK#3 What I am considering next is setting up an array spriteNum =[] and then put face numbers in the array and use something likespriteRow = spriteNum[f] % hSpriteNb;spriteColumn = Math.floor(spriteNum[f] / hSpriteNb); I'll look forward to your CreatePolyhedron jerome and Wingnut 2 Quote Link to comment Share on other sites More sharing options...
jerome Posted October 11, 2015 Share Posted October 11, 2015 Really nice The middle of each face is quite easy to compute : barycenter.You just need the middle location to compute then the location of each vertex of the polygon, as you need with your own rotation.I don't think that you need to add this middle point to the positions array : all you want to get is the 2D coordinates of your (face) polygon vertices on your texture. The circumcircle method is easy (probably not the most optimized in terms of texture surface cropping) if you have to deal with polygons with more than 4 sides, what is not your case if you want to keep indeed your code dedicated to this kind of polyhedrons having only triangular and squared faces.This was just a suggestion in order to generalize the code to any polyhedron types. I like a lot the 126 samples with the sprites Quote Link to comment Share on other sites More sharing options...
jerome Posted October 12, 2015 Share Posted October 12, 2015 Please forget what I said about the barycenter. Your technique works obviously by rotating in turn from a starting point !I didn't read it well yesterday. Actually, I just did the same in CreateDisc() but with another rotation because of a different indices order. I like yours, I will borrow (steal) it for the CreatePolygon implementation Quote Link to comment Share on other sites More sharing options...
JohnK Posted October 12, 2015 Author Share Posted October 12, 2015 Steal away. Quote Link to comment Share on other sites More sharing options...
jerome Posted October 12, 2015 Share Posted October 12, 2015 thank you So I borrowed a part of you code, injected it in my original code (which was yet a port from Stemkosky's one in threejs) and cleaned up everything.http://www.babylonjs-playground.com/#21QRSK#4 (switch the editor off to display the names) The main program starts from the line 126.It's not TS for now (ported very soon), but a quite achieved JS draft.The signature is :CreatePolyhedron("name", options, scene);details of the option properties (all optional) :type : not implemented yet, will be one of the polyhedron type provided in the core. This will be documented.custom: an expected polyhedron object if you want another type than the core ones, a copied/pasted variable from a extension file that will be onlinesize: no need to explainsizeX: the same only on XsizeY: only on YsizeZ: only on ZfaceUV: array(nbfaces) the same as for CreateBox => set your own image per facefaceColors: array(nbfaces) the same as for CreateBox => set your own color per face, as you can see in the exampleSame example with faceUV : http://www.babylonjs-playground.com/#21QRSK#5Both (colors and faceUV) : http://www.babylonjs-playground.com/#21QRSK#6 JohnK 1 Quote Link to comment Share on other sites More sharing options...
JohnK Posted October 12, 2015 Author Share Posted October 12, 2015 Brilliant piece of tidying up and consistantising (new word just made it up - hope it doesn't catch on ) Go Team JJ Quote Link to comment Share on other sites More sharing options...
jerome Posted October 12, 2015 Share Posted October 12, 2015 Now, I still have to make the (hard) choice of what polyhedron type to include in the core and what type to keep apart.I will lighten the big JSON file also by removing all the data relative to the edges as we don't need them. Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted October 12, 2015 Share Posted October 12, 2015 I'm only for those with a name like tyranosodron or toolongnamedron jerome and JohnK 2 Quote Link to comment Share on other sites More sharing options...
JCPalmer Posted October 12, 2015 Share Posted October 12, 2015 The ones that you break out into the extension, I really hope that they are their OWN mesh subclass. BTW, do you have one that sort of looks like it could be a mesh proxy for a bone? See, http://wiki.blender.org/uploads/7/73/Manual-Part-I-Quick51.2.56.png I know bones do not have a length, well in BJS anyway Quote Link to comment Share on other sites More sharing options...
jerome Posted October 13, 2015 Share Posted October 13, 2015 started to port it to the core ... Quote Link to comment Share on other sites More sharing options...
jerome Posted October 13, 2015 Share Posted October 13, 2015 here is it : http://www.html5gamedevs.com/topic/17342-polyhedrons-first-attemp/?p=100654 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.