HoratioHuffnagel Posted December 1, 2017 Share Posted December 1, 2017 Hi, I am currently working on a game where I want to avoid using heavy physics systems. Mainly because I have size restrictions on downloads, and the physics requires a movement style like asteroids, but with no friction and a capped speed. Something that gets a little tricky with physics engines. So - Babylons's inbuilt physics system looks perfect - I can move the player with my own calculations, and just detect the collisions and react to that. Only problem is I'm not sure how to get the intersection point (i need to reflect the characters velocity when it hits a wall). let result = player.mesh.intersectsMesh(wall.mesh, true); So for instance - this is great... but only returns a boolean. I COULD cast a ray along the direction of travel, but that wont help if I clip the corner of an object. Any thoughts? Cheers. Quote Link to comment Share on other sites More sharing options...
Arte Posted December 1, 2017 Share Posted December 1, 2017 Hi @HoratioHuffnagel Similar topic Hope this information will help you . Sebavan and HoratioHuffnagel 2 Quote Link to comment Share on other sites More sharing options...
JohnK Posted December 2, 2017 Share Posted December 2, 2017 Here are some 'meteors(?)' colliding in a box https://www.babylonjs-playground.com/#CBYLEW The physics of collisions is based on the mathematics of spheres colliding. Each meteor is a sphere with vertices moved randomly by a small amount based on Temechon's work on tree generation. More on the mathematics of collisions used can be found here http://doc.babylonjs.com/samples unfortunately on these pages the diagrams to help are missing. I have now submitted the images but they will only be available on the next deployment of the documention. As this uses the SPS system all meteors are identical in shape except for some random scaling along the x, y and z axis. However the same process can be done with individual meshes. Hope this helps Sebavan, Arte and HoratioHuffnagel 3 Quote Link to comment Share on other sites More sharing options...
HoratioHuffnagel Posted December 4, 2017 Author Share Posted December 4, 2017 (edited) [EDIT: I have added a new post, because I realised the error was wetware - I really should have seen this problem myself. ] Thanks guys - this is somewhat helpful (it has shown me a lot of promising possibilities for sure!), but every path I follow isn't quite there. All I want is a collision event, and a normal. This is insanely difficult to do apparently... grr. let mesh1 = player.mesh; let mesh2 = wall1.mesh; mesh1.actionManager = new BABYLON.ActionManager(renderer.scene); mesh1.actionManager.registerAction(new BABYLON.SetValueAction( { trigger: BABYLON.ActionManager.OnIntersectionEnterTrigger, parameter: mesh2 }, "scaling", new BABYLON.Vector3(1.2, 1.2, 1.2))); // This is directly from the documentation but results in the following error // babylon.js:25 Uncaught TypeError: t.split is not a function // This is being thrown from the registerAction method by the looks Does anyone have any idea what this error may be caused by? Edited December 4, 2017 by HoratioHuffnagel I made a stupid error. ;) Quote Link to comment Share on other sites More sharing options...
HoratioHuffnagel Posted December 4, 2017 Author Share Posted December 4, 2017 Okay - so the secret is to rant on a forum, then the answer will come immediately too you. My error was to pass a new SetValueAction instead of ExecuteCodeAction. Wow - I really should have seen that! So - thank you very much guys - it's been a couple of days of digging through documentation, but you both gave me some excellent resources to read! However - I do now have one last question - I have this collision event - but I can't seem to find what would constitute the normal of the collision? Any ideas? Quote Link to comment Share on other sites More sharing options...
JohnK Posted December 4, 2017 Share Posted December 4, 2017 For a wall and a sphere the collision normal is the normal of the wall. For two spheres the collision normal is the line joining their centres. My meteor PG assumes a bounding sphere for the meteors. For other shapes things get really complicated. Take to meshes A and B made up of triangular facets with facets FA and FB in contact. If FA and FB are parallel (unlikely) then the collision normal is the normal of the two facets. If they are not parallel then some other decisions on how to interpret what is happening at the collision area need to be made, for example use the line joining the Barycentres of the facets FA and FB. Alternatively you could use a bounding ellipsoid for the the two meshes A and B An ellipsoid with centre at the origin and in alignment to the axes will have an equation of the form ax2 + bx2 + cx2 = d When P = (p, q, r) is on the surface of the ellipsoid then the normal at P will have the form (ap, bq, cr). When two ellipsoids C and D meet in space let Q = (s, t, u) be the point of contact. Now for the ellipsoid to be where they are they will have undergone rotation and translation. Let T be the transformation matrix applied to C then CT -1 will return the ellipsoid C back to centre origin and in alignment with the axes and QT -1 will be the point on the surface where contact was made on the ellipsoid CT -1. Using the x, y, z values for the point QT -1 with the equation of CT -1 will give you the normal N and so NT will be the collision normal for the two ellipsoids. Which is why I stuck to spheres. Quote Link to comment Share on other sites More sharing options...
HoratioHuffnagel Posted December 4, 2017 Author Share Posted December 4, 2017 Yes, I know it is the normal of the wall - the question is how do I obtain it? If I have a set of walls in an environment, I have successfully coded number of ways to determine if there is a collision, using OnIntersectionEnterTrigger, or intersectMesh - each time I find myself stuck with either not enough, or too much information. Now - I know that is user error more than anything - it's just that I am up against the clock and have to get something working soon. I should also mention - this is an environment that will have walls - in a maze like layout - think Pacman - player can navigate freely through the environment, and collide with walls, rebounding off them - and there will be no friction (so they need to rebound constantly). So this is where I am at: I am choosing to use moveWithCollision (so I can just write my own movement routines) I have settled on OnIntersectionEnterTrigger to get the collision event At this point I have an enormous data structure (returned in the callback for OnIntersectionEnter) and I can't tell what is actually useful for getting the normal of the face I hit. I will also like need to the collision point, as I will need to reposition the player outside the wall (as they may continue to apply force in the direction of the collision) One way would be to use a ray test - but it seems the collision event SHOULD have the data in there somewhere? Thanks Quote Link to comment Share on other sites More sharing options...
Wingnut Posted December 4, 2017 Share Posted December 4, 2017 Hi guys! I saw a nice BJS pacman-like demo, once. I believe it was coded by forum friend @BitOfGold https://www.babylonjs-playground.com/#LYCSQ#256 Perhaps some collision techniques could be borrowed from that. *shrug* HoratioHuffnagel 1 Quote Link to comment Share on other sites More sharing options...
HoratioHuffnagel Posted December 4, 2017 Author Share Posted December 4, 2017 I've had a look at that code before - it doesn't need or consume the face normals. The reason I need normals is because the user can move with continuous velocity in a single direction. When they hit the wall, they must 'reflect' off the wall. Basically like pong. The only problem is, unlike pong, I don't know the orientation of the wall ahead of time. While many games wont require it, it's common enough to need to know (i.e. projectile hits wall, what direction should particles spray out etc). Wingnut 1 Quote Link to comment Share on other sites More sharing options...
hunts Posted December 4, 2017 Share Posted December 4, 2017 i'm working on a steering library, i used this to bounce off walls: if(this.player.intersectsMesh(obstacle)){ this.player.position = BABYLON.Vector3.Lerp(this.player.position, new BABYLON.Vector3(obstacle.position.x, 0, obstacle.position.z).scale(100).negate(), this.alpha); this.player.position.scale(this.radius).normalize(); } But if you intend to use raycaster, you can use the same approach. HoratioHuffnagel 1 Quote Link to comment Share on other sites More sharing options...
HoratioHuffnagel Posted December 4, 2017 Author Share Posted December 4, 2017 I think I have it - thanks for the advice everyone. I will do up a playground to demonstrate the result once I have had some sleep. But the basics are: Use moveWithCollisions to do movement Setup AABB boxes as children of the obstacles (use this to detect collisions) Setup OnIntersectionEnterTrigger actions on the player object When a collision is detected, do a ray cast (up, down, left, right) to determine where the collision was using intersectsMeshes The object that is returned will let me get the normal using .getNormal @huntsYour solution also looks completely valid - I might give that a go too to see what is more performant. Thanks again. Cheers! Quote Link to comment Share on other sites More sharing options...
Wingnut Posted December 4, 2017 Share Posted December 4, 2017 Nice work, HH, and thx for the promise of the demo PG. We will look forward to that. I have a dumb question (I'm not noob to collisions, but I DO forget everything I've EVER learned... once per month) ... If you were to constantly "record" the lastPlayerMovementDirection... so you could "have" the direction of impact that caused collision... then couldn't that, and the wall's y-rotation (and a bit of simple math)... be used to derive a rebound direction? Sorry about being simpleton. I'm more polyhedrArtist (TinkerToy Engineer) than mathematician or programmer. Quote Link to comment Share on other sites More sharing options...
JohnK Posted December 4, 2017 Share Posted December 4, 2017 When a wall is created and positioned can you not make the normal a property of the wall. You could also check this out http://doc.babylonjs.com/how_to/how_to_use_facetdata In particular getFacetsAtLocalCoordinates and getFacetNormal EDIT Started this answer a couple of hours ago on my mobile while waiting for an appointment. Finished it when I got home before checking for replies. Answer is probably now redundant. HoratioHuffnagel 1 Quote Link to comment Share on other sites More sharing options...
Wingnut Posted December 4, 2017 Share Posted December 4, 2017 Perhaps reinforcing, or reiterating, but your words are NEVER EVER redundant, JK. Honey on country biscuits, my man. HoratioHuffnagel and JohnK 1 1 Quote Link to comment Share on other sites More sharing options...
HoratioHuffnagel Posted December 5, 2017 Author Share Posted December 5, 2017 Yeah - definitely not redundant. I had a look at the facet data route - but oddly, with the event that came back it always looked like the facet id was 0. I may have been look at it wrong - but it was part of the confusion. Anyway - solved, and thanks again. Will make sure I get a demo up later today. 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.