celian-garcia Posted July 2, 2014 Share Posted July 2, 2014 Hello !I made a createSubdividedCylinder() function and I am relatively proud of me ^^ Here is the result : But making it, I found some issues : firstly, the diameterTop, and diameterBottom are inversed ! For example : when I write it// My function var myVertexData = createSubdividedCylinder(1, 1, 0.5, 16);var myCylinder = new BABYLON.Mesh("myCylinder", scene);myVertexData.applyToMesh(myCylinder);myCylinder.position.x = -2;// Babylon functionvar babylonVertexData = new BABYLON.VertexData.CreateCylinder(1, 1, 0.5, 16);var babylonCylinder = new BABYLON.Mesh("babylonCylinder", scene);babylonVertexData.applyToMesh(babylonCylinder);babylonCylinder.position.x = 2; We do not obtain the same result whereas both functions have the same header :var createSubdividedCylinder = function (height, diameterTop, diameterBottom, tessellation, subdivisions) {...};VertexData.CreateCylinder = function (height, diameterTop, diameterBottom, tessellation) {...};Secondly, when we do not have the same diameterBottom & diameterTop, normals are not really the good ones.- The first picture shows us what we want- second one shows what we have currently.Of course blue arrows materializes normals and gray trapeze is the cylinder I fixed the first bug but the second is harder to fix so I prefered make a "BABYLON.VertexData.ComputeNormals" after creation to have the good normals. Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted July 2, 2014 Share Posted July 2, 2014 Just for the sake of my comprehension: the bug is your code or mine? Quote Link to comment Share on other sites More sharing options...
Dad72 Posted July 2, 2014 Share Posted July 2, 2014 From what I understand he was in Babylon Quote Link to comment Share on other sites More sharing options...
celian-garcia Posted July 2, 2014 Author Share Posted July 2, 2014 Both of them are from your code but I only fixed the first one (about inversed diameters) in my createSubdividedCylinder() function Quote Link to comment Share on other sites More sharing options...
celian-garcia Posted July 2, 2014 Author Share Posted July 2, 2014 In fact I could try to resolve the second bug (about normals) and prepare a pull request. It would add at the same time the possibility to create subdivided cylinder too. I precise than the function would have exactly the same behaviour than yours but with an additionnal and optionnal parameter : subdivisions, by default equal to 1. Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted July 2, 2014 Share Posted July 2, 2014 Sounds good Quote Link to comment Share on other sites More sharing options...
celian-garcia Posted July 3, 2014 Author Share Posted July 3, 2014 Cool ! I'm working on it Quote Link to comment Share on other sites More sharing options...
celian-garcia Posted July 7, 2014 Author Share Posted July 7, 2014 I surrender ! In fact I had nice values for the normals but these normals was coming from vertices and not faces. And I saw in the computeNormals function that normals have to be computed for faces. So my results are very closed to computeNormals ones but not exactly sames. It is not really surrending cause I'll make a simple call to the magical computeNormals function at the end like it has be done for the torusknot ^^. So the new CreateCylinder function is coming soon ! Here is a comparison in pictures : With old function CreateCylinder : With the new function (trying to compute normals) With the new function and computeNormals function (the one I'll make finally) Quote Link to comment Share on other sites More sharing options...
celian-garcia Posted July 7, 2014 Author Share Posted July 7, 2014 Pull request done ! Quote Link to comment Share on other sites More sharing options...
celian-garcia Posted July 7, 2014 Author Share Posted July 7, 2014 Here is the code of the new function CreateCylinder if somebody want :VertexData.CreateCylinder = function (height, diameterTop, diameterBottom, tessellation, subdivisions) { var radiusTop = diameterTop / 2; var radiusBottom = diameterBottom / 2; var indices = []; var positions = []; var normals = []; var uvs = []; height = height || 1; diameterTop = diameterTop || 0.5; diameterBottom = diameterBottom || 1; tessellation = tessellation || 16; subdivisions = subdivisions || 1; subdivisions = (subdivisions < 1) ? 1 : subdivisions; var getCircleVector = function (i) { var angle = (i * 2.0 * Math.PI / tessellation); var dx = Math.cos(angle); var dz = Math.sin(angle); return new BABYLON.Vector3(dx, 0, dz); }; var createCylinderCap = function (isTop) { var radius = isTop ? radiusTop : radiusBottom; if (radius == 0) { return; } var vbase = positions.length / 3; var offset = new BABYLON.Vector3(0, height / 2, 0); var textureScale = new BABYLON.Vector2(0.5, 0.5); if (!isTop) { offset.scaleInPlace(-1); textureScale.x = -textureScale.x; } // Positions, normals & uvs for (i = 0; i < tessellation; i++) { var circleVector = getCircleVector(i); var position = circleVector.scale(radius).add(offset); var textureCoordinate = new BABYLON.Vector2( circleVector.x * textureScale.x + 0.5, circleVector.z * textureScale.y + 0.5 ); positions.push(position.x, position.y, position.z); uvs.push(textureCoordinate.x, textureCoordinate.y); } // Indices for (var i = 0; i < tessellation - 2; i++) { if (!isTop) { indices.push(vbase); indices.push(vbase + (i + 2) % tessellation); indices.push(vbase + (i + 1) % tessellation); } else { indices.push(vbase); indices.push(vbase + (i + 1) % tessellation); indices.push(vbase + (i + 2) % tessellation); } } }; var base = new BABYLON.Vector3(0, -1, 0).scale(height / 2); var offset = new BABYLON.Vector3(0, 1, 0).scale(height / subdivisions); var stride = tessellation + 1; // Positions, normals & uvs for (var i = 0; i <= tessellation; i++) { var circleVector = getCircleVector(i); var textureCoordinate = new BABYLON.Vector2(i / tessellation, 0); var position, radius = radiusBottom; for (var s = 0; s <= subdivisions; s++) { // Update variables position = circleVector.scale(radius); position.addInPlace(base.add(offset.scale(s))); textureCoordinate.y += 1 / subdivisions; radius += (radiusTop - radiusBottom)/subdivisions; // Push in arrays positions.push(position.x, position.y, position.z); uvs.push(textureCoordinate.x, textureCoordinate.y); } } subdivisions += 1; // Indices for (var s = 0; s < subdivisions - 1; s++) { for (var i = 0; i <= tessellation; i++) { indices.push( i * subdivisions + s); indices.push((i * subdivisions + (s + subdivisions)) % (stride * subdivisions)); indices.push( i * subdivisions + (s + 1)); indices.push( i * subdivisions + (s + 1)); indices.push((i * subdivisions + (s + subdivisions)) % (stride * subdivisions)); indices.push((i * subdivisions + (s + subdivisions + 1)) % (stride * subdivisions)); } } // Create flat triangle fan caps to seal the top and bottom. createCylinderCap(true); createCylinderCap(false); // Normals BABYLON.VertexData.ComputeNormals(positions, indices, normals); // Result var vertexData = new BABYLON.VertexData(); vertexData.indices = indices; vertexData.positions = positions; vertexData.normals = normals; vertexData.uvs = uvs; return vertexData;}; 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.