xiuhtecuhtle Posted November 6, 2016 Share Posted November 6, 2016 What is the best approach to determining what face of a mesh was hit in a collision? I'm creating a game in which there are very many meshes; they are platforms onto which the player can jump. But if the player hits the side of any platform, he dies. As far as I can think, there are two approaches here: 1. Find some way of determining which vertex set was hit, get the normal to it, and record whether the normal points in the (0,1,0) direction (OK) or otherwise (kills player). However, I can only find a way of telling when two meshes collide. The PhysicsImpostor.registerOnPhysicsCollide callback only tells me which meshes are hit. Perhaps once I have the two meshes there is a way to tell which vertex set of one mesh intersects which vertex set of another - but if such a function exists I couldn't find it. (Closest thing is the PickingInfo returned by AbstractMesh.intersects(Ray) - but that's not quite what I need, as far as I can tell). 2. Add additional meshes to the scene to "cover" the platforms. So I could for example add a plane to the top face of each platform and say that if the player collides with it then he's safe, otherwise if he collides only with the platform then he's not. This approach seems inefficient as it doubles the number of meshes. Also would it even work? Say there is a platform that's a cube, and the player hits the side with normal (0,0,-1). That should kill him, but if he hits it near the top he may also just touch the edge of the cover - which by the logic above would save him. Thanks for any pointers! Quote Link to comment Share on other sites More sharing options...
Wingnut Posted November 8, 2016 Share Posted November 8, 2016 Hiya @xiuhtecuhtle, welcome to the forum! Sorry it is taking so long to get replies. I would start with a search of our playgrounds... for "collider". http://doc.babylonjs.com/playground?q=collider&page=1&max=86 I think you can reference a collider with mesh._collider. Collider source code shows that there are many delicious properties on Colliders. They are _private properties, but you can use/query them. Take a look at this playground. There is some use of a _collider object, there. Sorry I don't have more info. Speaking of info, let's look at pickingInfo... http://doc.babylonjs.com/classes/2.4/PickingInfo How about that .faceId property? That might be a good word to use in a playground search and forum search. I hope this helps. Others will comment, soon, perhaps. Be well, welcome again. GameMonetize 1 Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted November 9, 2016 Share Posted November 9, 2016 @Wingnut is right: just use the faceID to get the face number.From this face number you can get the indices from mesh.getIndices(). So if you want the first vertex from faceID: mesh.getIndices()[faceID * 3] Quote Link to comment Share on other sites More sharing options...
xiuhtecuhtle Posted November 12, 2016 Author Share Posted November 12, 2016 Awesome, thanks @Wingnut and @Deltakosh. You pointed me in the right direction - what I do is cast a ray from the centre of one mesh to the centre of the other and use scene.pickWithRay to get the PickingInfo. No need in fact to get faceId to get the normal: PickingInfo has its own getNormal() method. This isn't perfect - you could quite easily conceive of a situation where two meshes collide but the ray cast from the centre of one to the centre of the other doesn't intersect the collided faces. But it's good enough for my purposes. Incidentally, PickingInfo.getNormal(false, false) sometimes returns a normal in the wrong direction. Ie the face hit has normal (0,0,-1) and getNormal returned (0,0,1). The solution, for anyone interested, is to use PickingInfo.getNormal(false, true). Here's my code: var didHitSideOfPlatform = function (ship, platform) { var ray = new BABYLON.Ray(ship.position, platform.position.subtract(ship.position)); var pickInfo=scene.pickWithRay(ray, function (item) { return item == platform }); if (pickInfo.hit) { var normal = pickInfo.getNormal(false, true); return Math.abs(normal.x) < 0.01 && Math.abs(normal.y) < 0.01; } return false; } Thanks again Virax and Wingnut 2 Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted November 14, 2016 Share Posted November 14, 2016 This is cool! Quote Link to comment Share on other sites More sharing options...
Wingnut Posted November 14, 2016 Share Posted November 14, 2016 Woah, pickingInfo has a getNormal? Well shoooooot... that is exactly what we are seeking... in another thread! Excellent! hmm. Thanks for the demo code, X! 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.