Sign in to follow this  
UP_AND_ATOM

Getting strange results for vertices

Recommended Posts

I'm a JS developer using Babylon.js for the first time, and right now I'm just trying develop an understanding of what is happening under the hood. I've been programming forever, but have limited 3D experience, so Babylon.js looks like a perfect learning opportunity.

 

I put together a simple program that takes a mesh, finds the screen coordinates of each of its vertices, and overlays triangles on a canvas on top of Babylon.js's renderCanvas. I'm getting some strange results, though. Most of the vertices are right where they should be, but others are completely wrong. When I do this with a cube, all the verticies look right, but if I open up the vertices array, what I'm seeing on-screen doesn't match the data. Screenshot: http://i.imgur.com/POtcnBr.png

 

It's a bit simpler with a plane. All four vertices make a square using only X and Y, which is exactly what I would expect. For some reason when I run my program, the scene coordinates for vertices 0 and 1 end up floating in space, while 2 and 3 are right where they should be. Screenshot: http://i.imgur.com/s4e0HlH.png

 

Not sure if it helps, but it gets even weirder with a sphere. Screenshot: http://i.imgur.com/pQU9yXg.png

 

I guarantee I'm just missing something simple, probably in the getScreenCoords function, but so far I haven't had any luck. Am I just misusing the indices array? It seems that each number in the indices array corresponds to a specific vertex. I have a feeling that's what is failing, but so far I haven't been able to nail it down.

 

Here's the function that does the work:

  engine.beginFrame = function() {    box.rotation.y += 0.005;    box.rotation.x += 0.003;    ctx.clearRect(0, 0, drawCanvas.width, drawCanvas.height);    ctx.fillStyle = 'rgba(255, 43, 0, 0.25)';    ctx.strokeStyle = 'black';        var vertexCoords = [];        var vertices = box.getVerticesData(BABYLON.VertexBuffer.PositionKind);    var indices = box.getIndices();    for (var i=0, len=indices.length; i<len; i+=3) {      for (var v=0; v<3; v++) {        var index = indices[i+v];        if(!vertexCoords[index]) {          vertexCoords[index] = getScreenCoords(BABYLON.Vector3.FromArray(vertices, index), box);          ctx.fillRect(vertexCoords[index].x-4, vertexCoords[index].y-4, 8, 8);        }      }      ctx.beginPath();      ctx.moveTo(vertexCoords[indices[i+2]].x, vertexCoords[indices[i+2]].y);      ctx.lineTo(vertexCoords[indices[i+0]].x, vertexCoords[indices[i+0]].y);      ctx.lineTo(vertexCoords[indices[i+1]].x, vertexCoords[indices[i+1]].y);      ctx.lineTo(vertexCoords[indices[i+2]].x, vertexCoords[indices[i+2]].y);      ctx.stroke();      ctx.fill();      ctx.closePath();    }  };      var getScreenCoords = function(vertex, mesh) {    var coords = BABYLON.Vector3.Project(      BABYLON.Vector3.TransformCoordinates(vertex, mesh.getWorldMatrix()),      BABYLON.Matrix.Identity(),       scene.getTransformMatrix(),       camera.viewport.toGlobal(engine)    );    return coords;  };

Share this post


Link to post
Share on other sites

Just a guess but it doesn't look like the camera's transform is getting used. I'd have thought you might need the camera's view matrix (or projection matrix?) multiplied onto the transform you pass to Project. Does rotating the camera affect the outlines?

 

By the way, check out the BJS playground. If you code up your example in there, you can easily share us a link that we can play with, fork and send you updates, etc. It's honestly one of the greatest things about BJS.

Share this post


Link to post
Share on other sites

You are using indices correctly, as far as I see. Try with this function:

var getScreenCoords = function(vertex, mesh) {	  var transformationMatrix = camera.getViewMatrix().multiply(camera.getProjectionMatrix());    var coords = BABYLON.Vector3.Project(vertex,      mesh.getWorldMatrix(),       transformationMatrix,       camera.viewport.toGlobal(engine)    );    return coords;  };

It is using the camera's view and projection matrix to get the correct transformation matrix, and is not first transforming the vertex using the transformation matrix, but using it in the project function. Easier to debug, if you use the playground - http://www.babylonjs-playground.com/#S7Z2Z , as fenomas said :-)

 

EDIT:

 

Found your mistake in the calculation. Your getScreenCoords function is fine... You are missing one little thing:

vertexCoords[index] = getScreenCoords(BABYLON.Vector3.FromArray(vertices, index *3 ), box);

index * 3 is the correct position. That was the problem :) here - http://www.babylonjs-playground.com/#S7Z2Z#1

Edited by RaananW

Share this post


Link to post
Share on other sites

Just out of curiosity, is there a recommended way to check if a given vertex is visible to the camera? I've tried using scene.pick(x, y).distance and comparing the actual distance between the camera and vertex, but that seems a little hacky and probably won't scale too well for larger meshes.

Share this post


Link to post
Share on other sites

If it's a convex mesh and you just want to know which vertices are hidden by that mesh itself, then basically that's backface culling. In general I think you'd need to check normals per face though, not per vertex.

If you want to find whether vertices are hidden by anything, including other meshes, AFAIK you'd need to analytically check the vertex against each poly that could obscure it, or else use something like a depth buffer (so, basically render the scene).

Share this post


Link to post
Share on other sites

The only way I can think of is raytracing (technically, what scene.pick is doing). maybe with fast check (meaning - if the first mesh that was hit by the ray is not his mesh, then it should stop searching for further meshes). But, as You said, would probably not scale the best.

Share this post


Link to post
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...
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.