aWeirdo Posted February 11, 2017 Share Posted February 11, 2017 Hi all, Update - 17 / 02 mesh.collisionGroup = maskNumber; have been added to AbstractMesh. Two new properties, collisionGroup and collisionMask, have been added to AbstractMesh, collisionMask have been added to FreeCamera, and is coming with 2.6. Why? What do they do? The collisionGroup & collisionMask checks whether a camera Vs mesh or mesh Vs mesh collision should happen. Thus, it allows us to customize collisions, enabling us to decide what meshes should collide with each other and which meshes should collide with the camera An example could be to have collisions between the camera and a box aswell as the camera and a sphere, but no collision between the sphere and the box all at the same time. Once it's live, it will work like this; var group1 = 1; // x to the power of 2, starting from 1. var group2 = 2; // 1*2 = 2 var group3 = 4; // 2*2 = 4 var group4 = 8; // 4*2 = 8, and so on. // This mesh is part of the group1 collisionGroup, camera's and other (moving) meshes with group1 in their collisionMask will collide with this mesh. mesh.collisionGroup = group1; // While moving, this mesh will collide with other meshes which has either group1 or group2 as their collisionGroup mesh.collisionMask = group1 + group2; // While moving, the camera will collide with meshes which has either group1 or group2 as their collisionGroup camera.collisionMask = group1 | group2; // doing group1 | group2 has the same effect as, but is less dynamic than, group1 + group2 You can also do; camera.collisionMask = group1; // Set mask to collide with group1. camera.collisionMask += group2; // Set mask to also collide with group2. camera.collisionMask -= group1; // Remove group1 from mask so we only collide with group2. // Take careful note before using this method, to avoid issues, you must first override the default mask (-1) by doing cameraOrMesh.collisionMask = your_group_x_variable; It is currently not available for webworkers. Backwards compatibility, If this isn't something that interests you, you're all good, nothing has changed. Masks Masks are numbers to the power of 2, starting from 1. Special masks -1 ; Always collides. 0 ; Never collides, overrides mask -1. // not recommended to use on camera with standard gravity applied.Standard masks , x to the power of 2; 1 | 1*2 = 2 | 2*2 = 4 | 4*2 = 8 | 8*2 = 16 | etc. 1 2 4 8 16 Etc PG Example; The camera collides with the ground & box, but not with the sphere and the sphere and box doesn't collide with each other either. http://www.babylonjs-playground.com/#20PQBI#43 Cheers. If you have any questions, ideas or thoughts, please do continue the discussion below. Dad72, getzel and JackFalcon 3 Quote Link to comment Share on other sites More sharing options...
aWeirdo Posted February 11, 2017 Author Share Posted February 11, 2017 Sorry if anyone got errors in the PG, babylon.js v2.6-alpha was just updated and rendered old PGs useless, it's now been updated Quote Link to comment Share on other sites More sharing options...
Dad72 Posted February 11, 2017 Share Posted February 11, 2017 Thank you for this feature. I have a hard time understanding everything. If I want all the characters to collide with the objects in the scene, but not between them, which mask should I use? If all my characters have a mask of 2, they will be in collision. I have a function that create all my characters, so they have an identical mask, so we will collide with each other. I have a hard time understanding how it works. If I remember at the beginning, it was the identical masks that will not be in collision but collide with any lower value mask. Quote Link to comment Share on other sites More sharing options...
aWeirdo Posted February 11, 2017 Author Share Posted February 11, 2017 hi @Dad72 Sorry for my bad explaination, i will update it in a few minutes, i made it a lot harder than it have to be Okay, updated, you want objects to always collide, leave them at -1. you want your npc's & players to never collide, give them a unique mask, var nextMask = 1; //global variable newPlayer.collisionMask = nextMask; //set unique mask nextMask *= 2; //update nextMask Quote Link to comment Share on other sites More sharing options...
aWeirdo Posted February 11, 2017 Author Share Posted February 11, 2017 At the moment, mask 0 overrides all masks and no collision at all happens, as if collisions where disabled for that mesh, because Math . We could hard-code the mask 0 to not override -1, so e.g. if mask is set to 0, you only collide with mask -1, That would simplify the situation where you have a large group of meshes that shouldn't collide each other but should collide with other meshes like the ground mesh. would need to get @Deltakosh thoughts on that though. Quote Link to comment Share on other sites More sharing options...
Dad72 Posted February 11, 2017 Share Posted February 11, 2017 I had imagined that the identical mask would not collide, but it will be with the mask of lower value. This is what you had done with the filters previously. All the characters in my case will have an identical mask to their creation and will therefore collide with each other. I understood better the method with the filters previously. Should not the identical mask not collide, but only with the asci of lower value? Quote Link to comment Share on other sites More sharing options...
aWeirdo Posted February 12, 2017 Author Share Posted February 12, 2017 I was downvoted on that setup, For now, you can leave all objects, walls, floors & ground meshes at -1, and just create a global mask variable, something like this; var globalMask = .5; //first mask will be 1. function getNewMask(){ return globalMask *=2; } function createPlayer(/* ... */){ var newPlayer = playerMesh.clone('newPlayer'); newPlayer.collisionMask = getNewMask(); } Quote Link to comment Share on other sites More sharing options...
Dad72 Posted February 12, 2017 Share Posted February 12, 2017 Your method is interesting, but I only create 1 character per computer (it's for a network game, so many characters on the scenes, but per customer), so this global variable will be the same for each client and will not be Do not increase unless I add it in a global file for everyone (I can get it, but that means that 1, 2, 4, 8, 16, 32, 64... will not collide with each other? ) Quote Link to comment Share on other sites More sharing options...
adam Posted February 12, 2017 Share Posted February 12, 2017 My vote is for collisionGroups + collisionMasks. Then you can define your groups assign them to meshes and then apply a collisionMask to your meshes. var group1 = 1; var group2 = 2; var group3 = 4; mesh1.collisionGroup = group1; mesh1.collisionMask = group1 | group3; //mesh will collide with group1 and group3 mesh2.collisionGroup = group2; mesh2.collisionMask = group1; //mesh only collides with group1 mesh3.collisionGroup = group3; mesh3.collisionMask = group1 | group2; //mesh collides with group1 and group2 Dad72 1 Quote Link to comment Share on other sites More sharing options...
Dad72 Posted February 12, 2017 Share Posted February 12, 2017 I really like this idea. It would work. Quote Link to comment Share on other sites More sharing options...
aWeirdo Posted February 12, 2017 Author Share Posted February 12, 2017 I'm not a big fan of the collisionGroup setup tbh, it can quickly cause problems and turn into a situation like your example @adam if mesh2 moves it collides with mesh1, but if mesh1 moves it doesn't collide with mesh2 If you guys really want collisionGroups, i do have a PR ready that will add them, but we can also turn around how the masks works. so instead of same masks colliding with each other, same masks would instead ignore collisions. so; ground.collisionMask = 0; // always collides. mesh1.collisionMask = group 1; //mesh1 collides with ground, mesh2 & mesh3. mesh2.collisionMask = group 2; //mesh2 collides with ground & mesh1, but not with mesh3. mesh3.collisionMask = group 2; //mesh3 collides with ground & mesh1, but not with mesh2. http://www.babylonjs-playground.com/#20PQBI#31 Dad72 1 Quote Link to comment Share on other sites More sharing options...
adam Posted February 12, 2017 Share Posted February 12, 2017 Both Oimo and Cannon use this pattern. It just makes more sense to me to align with what other physics engines are doing. Maybe some other people can chime in. edit: My quick and dirty example above was to just show flexibility and ease of use. Quote Link to comment Share on other sites More sharing options...
aWeirdo Posted February 12, 2017 Author Share Posted February 12, 2017 @adam it would be nice being able to just mesh.collidesWith.push(thisOrThatGroup), I've thought about doing something along those lines to allow more dynamic changes to what should collide. but it would mean that we have to run another loop in the collision code for each single mesh to compare the groups, a short loop, but still a loop. Quote Link to comment Share on other sites More sharing options...
Dad72 Posted February 12, 2017 Share Posted February 12, 2017 It's a good solution also like that aWeirdo. You are going PR this solution? http://www.html5gamedevs.com/topic/28373-new-property-collisionmask-added-to-babylon-collisions-non-physics-engine/?do=findComment&comment=163119 Quote Link to comment Share on other sites More sharing options...
adam Posted February 12, 2017 Share Posted February 12, 2017 21 minutes ago, aWeirdo said: @adam it would be nice being able to just mesh.collidesWith.push(thisOrThatGroup), I've thought about doing something along those lines to allow more dynamic changes to what should collide. but it would mean that we have to run another loop in the collision code for each single mesh to compare the groups, a short loop, but still a loop. I deleted that post, because I didn't want to overwhelm. Since you commented on it, I'll try to recreate it: Better yet, it would be cool if you could keep the numbers under the hood and do something like this: mesh1.collisionGroup = "group1"; mesh1.collisionMask = ["group1", "group2"]; mesh2.collisionGroup = "group2"; mesh2.collisionMask = ["group1", "group3"]; mesh3.collisionGroup = "group3"; mesh3.collisionMask = ["group2", "group3"]; You wouldn't have to do a loop. You could create getters and setters for collisionGroup and collisionMask. You would be doing the same pattern I described above. None of it (such us the power of 2 group numbers) would be exposed to the user. Quote Link to comment Share on other sites More sharing options...
aWeirdo Posted February 12, 2017 Author Share Posted February 12, 2017 @adam I ment in the collision code itself, this is how it looks at the moment; for (var index = 0; index < this._scene.meshes.length; index++) { var mesh = this._scene.meshes[index]; if (mesh.isEnabled() && mesh.checkCollisions && mesh.subMeshes && mesh !== excludedMesh && ((collisionMask & mesh.collisionMask) !== 0)) { mesh._checkCollision(collider); } } if we turn the collider's collisionMask into an array, we would have to run another loop for each mesh inside the main loop Quote Link to comment Share on other sites More sharing options...
adam Posted February 12, 2017 Share Posted February 12, 2017 The user would set it up with an array, but when it is set, you would also be setting something like a private _collisionMask variable that is a number. You would still use bitwise comparision with that. No loop. Quote Link to comment Share on other sites More sharing options...
aWeirdo Posted February 14, 2017 Author Share Posted February 14, 2017 @adam a thought struck me, and in that case, a user can just do; mesh.collisionMask = group1: mesh.collisionMask += group2: aslong as the groups are x to the power of 2, starting from 1 ofc. On another note, collisionGroups are being added back for abstactMeshes. GameMonetize 1 Quote Link to comment Share on other sites More sharing options...
aWeirdo Posted February 17, 2017 Author Share Posted February 17, 2017 The thread & PG have been updated to include AbstactMesh.collisionGroup. Dad72 1 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.