auduct Posted May 13, 2015 Share Posted May 13, 2015 I am trying for object to object collision where cubes be dragged and stop when collided with another cube. surfed net for hours tried babylon.js documentations but no luck. you can see the problem online at this live link: http://websorce.com/babylon/2builtin_models.php The cube, torus, sphere can drag through each other, I need them to stop passing through each other. Here is the code I written var canvas = document.getElementById("renderCanvas"); var engine = new BABYLON.Engine(canvas, true); var createScene = function () { var scene = new BABYLON.Scene(engine); scene.clearColor = new BABYLON.Color3(0, 1, 0); var camera = new BABYLON.ArcRotateCamera("Camera", 3 * Math.PI / 2, Math.PI / 8, 50, BABYLON.Vector3.Zero(), scene); camera.attachControl(canvas, false); // This creates a light, aiming 0,1,0 - to the sky.var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene); // Dim the light a small amountlight.intensity = .5; //Creation of a box //(name of the box, size, scene) var box = BABYLON.Mesh.CreateBox("box", 6.0, scene); //Creation of a sphere //(name of the sphere, segments, diameter, scene) var sphere = BABYLON.Mesh.CreateSphere("Sphere", 10.0, 10.0, scene);var materialSphere3 = new BABYLON.StandardMaterial("texture3", scene); materialSphere3.diffuseTexture = new BABYLON.Texture("textures/z002.jpg", scene);sphere.material = materialSphere3; // Move the sphere upward 1/2 its height//sphere.position.y = .25; //Creation of a plane //(name of the plane, size, scene) var plane = BABYLON.Mesh.CreatePlane("plane", 10.0, scene); //Creation of a cylinder //(name, height, diamTop, diamBottom, tessellation, [optional height subdivs], scene, updatable) var cylinder = BABYLON.Mesh.CreateCylinder("cylinder", 3, 3, 3, 6, 1, scene, false); // Creation of a torus // (name, diameter, thickness, tessellation, scene, updatable) var torus = BABYLON.Mesh.CreateTorus("torus", 5, 1, 10, scene, false); // Creation of a knot // (name, radius, tube, radialSegments, tubularSegments, p, q, scene, updatable) var knot = BABYLON.Mesh.CreateTorusKnot("knot", 2, 0.5, 128, 64, 2, 3, scene); // Creation of a lines mesh var lines = BABYLON.Mesh.CreateLines("lines", [ new BABYLON.Vector3(-10, 0, 0), new BABYLON.Vector3(10, 0, 0), new BABYLON.Vector3(0, 0, -10), new BABYLON.Vector3(0, 0, 10) ], scene); // Moving elements box.position = new BABYLON.Vector3(-10, 0, 0); // Using a vector sphere.position = new BABYLON.Vector3(0, 10, 0); // Using a vector plane.position.z = 10; // Using a single coordinate component cylinder.position.z = -10; torus.position.x = 10; knot.position.y = -10; // Let's try our built-in 'ground' shape. Params: name, width, depth, subdivisions, scene var ground = BABYLON.Mesh.CreateGround("ground1", 26, 26, 2, scene); var startingPoint; var currentMesh; var getGroundPosition = function () { // Use a predicate to get position on the ground var pickinfo = scene.pick(scene.pointerX, scene.pointerY, function (mesh) { return mesh == ground; }); if (pickinfo.hit) { return pickinfo.pickedPoint; } return null; } var onPointerDown = function (evt) { if (evt.button !== 0) { return; } // check if we are under a mesh var pickInfo = scene.pick(scene.pointerX, scene.pointerY, function (mesh) { return mesh !== ground; }); if (pickInfo.hit) { currentMesh = pickInfo.pickedMesh; startingPoint = getGroundPosition(evt); if (startingPoint) { // we need to disconnect camera from canvas setTimeout(function () { camera.detachControl(canvas); }, 0); } } } var onPointerUp = function () { if (startingPoint) { camera.attachControl(canvas, true); startingPoint = null; return; } } var onPointerMove = function (evt) { if (!startingPoint) { return; } var current = getGroundPosition(evt); if (!current) { return; } var diff = current.subtract(startingPoint); currentMesh.position.addInPlace(diff); startingPoint = current; } canvas.addEventListener("pointerdown", onPointerDown, false); canvas.addEventListener("pointerup", onPointerUp, false); canvas.addEventListener("pointermove", onPointerMove, false); scene.onDispose = function () { canvas.removeEventListener("pointerdown", onPointerDown); canvas.removeEventListener("pointerup", onPointerUp); canvas.removeEventListener("pointermove", onPointerMove); }// Leave this function // Enable Collisions scene.collisionsEnabled = true; //Then apply collisions and gravity to the active camera camera.checkCollisions = true; camera.applyGravity = true; //Set the ellipsoid around the camera (e.g. your player's size) camera.ellipsoid = new BABYLON.Vector3(1, 1, 1);box.checkCollisions = true;cylinder.checkCollisions = true; return scene; }; // End of createScene function <?php //Create Scene Ends ?> // Now, call the createScene function that you just finished creating var scene = createScene(); // Register a render loop to repeatedly render the scene engine.runRenderLoop(function () {scene.render(); }); // Watch for browser/canvas resize events window.addEventListener("resize", function () {engine.resize(); }); 2builtin_models.php Quote Link to comment Share on other sites More sharing options...
Wingnut Posted May 14, 2015 Share Posted May 14, 2015 Ok, first, welcome to the forum, auduct! Good to have you with us! I'm Wingnut, local idiot and know-it-all wannabe, how ya doon? I hope well. I made a "playground demo" from your code. Here it is... http://playground.babylonjs.com/#1P9XIK I changed some little things, but nothing important. You have object dragging working well. But triggering the BabylonJS collision system... requires a special "move" function called .moveWithCollisions(). You can search this forum, and read LOTS of information about that function. Feel free to make changes to that playground demo... and then click RUN again, and then try something new, and click RUN again, and choose SAVE at anytime, and a new URL will show at the top. The SAVE is very safe in the playground. You will never over-write anything... by hitting save. And, use the 'get zip' option to take a version to your home, and play with it there. Notice line 93? It uses an 'addInPlace' method to .position the object. You need to replace this line... with SOME kind of .moveWithCollisions line. Search the forum for moveWithCollisions ... it's a heavily-discussed thing. Now that we have the playground scene that contains your code... you COULD go back and edit the previous post, and remove all that code. Everyone who is reading this topic, can now look at that playground, and see your code, and do experiments, and hit RUN, and do more saves, and tell us the urls to those saves, and and and... PARTY!!! Quote Link to comment Share on other sites More sharing options...
auduct Posted May 16, 2015 Author Share Posted May 16, 2015 First of all thanks a lot Wingnut for such a detailed reply. and thanks for putting the sample on playground. I have tried to apply moveWithCollisions() but no luck so far. can you help me with that? I am a beginner in this area so its a bit hard for me to write the code than experienced programmers. Quote Link to comment Share on other sites More sharing options...
Wingnut Posted May 16, 2015 Share Posted May 16, 2015 http://playground.babylonjs.com/#1P9XIK#2 Getting closer. I have "stuttery" drag problems, and collisions that look like earthquakes. I'm still studying it. Maybe the experts will help us out. update: I have a theory. I think our collision system has a 1-pixel back-off "feature" when a collision happens. After a collision, I think the moved mesh is told to back-away from the collision a tiny bit... to keep "continuous collision" from happening. My demo's drag code... ignores that phenomena, and just keeps dragging and causing further collisions and havoc. .moveWithCollisions is designed to back-away... from a "forward" collision. It is a forward-based function, used to walk characters, mostly. When we drag a mesh at angles that are NOT forward, the BJS collision system (via .moveWithCollisions) does the 1-pixel back-off... at the reverse angle of the direction that IT thinks the collision happened-at. Possibly, it "quantizes" (rounds the collision angle) into a forward/backward "motif". Thus, the 1-pixel back-away is getting totally confused as to WHAT ANGLE to do its back-away. This is compounded by the earlier problem... where I allow more dragging after a collision. Instead... possibly force a call to onPointerUp if a collision happens... might fix something. Hard to explain... and it's just a theory. Possibly, you/we are going to need a "special" moveWithCollisions function. Something like auductMoveWithCollisions() . Want to see the current .moveWithCollisions function? https://github.com/BabylonJS/Babylon.js/blob/master/Babylon/Mesh/babylon.abstractMesh.js#L619 Want to see how to STEAL that code from the BJS framework and make it YOURS? I knew ya did. http://playground.babylonjs.com/#1P9XIK#3 lines 4-10 ... your own special auductMoveWithCollisions(). I had to change some little things, but now... line 103 is calling YOUR auductMoveWithCollisions() function, and not the one in BJS. So you can do dangerous edits to auductMoveWithCollisions() and hit RUN again, and see what happens. Try stuff. Break stuff! Blow stuff up!!! YAY! Fun! Control-z in the playground editor... for un-do. Quote Link to comment Share on other sites More sharing options...
auduct Posted May 16, 2015 Author Share Posted May 16, 2015 Thanks a Lot for so much time and interest, I see this starting to work, do you think this bouncing of meshes on and below other meshes can be controlled? Quote Link to comment Share on other sites More sharing options...
Wingnut Posted May 19, 2015 Share Posted May 19, 2015 no. hehe (just kidding) New demo: http://playground.babylonjs.com/#1P9XIK#4 No problems fixed. Can't drag the linesMesh... so we got a 3rd problem, now. Yay! (I've begun SOME work on a ray-intersect method of selecting it - lines 141 to 151 ...not yet working. Experimental.) See lines 5-8? We need to figure out what the hell they do. See lines 11-19? We REALLY need to figure out what THEY do. heh See my brain? I wish someone could figure out why it doesn't already know everything. Still working and thinking, Auduct. How about you? Have you tried some experiments? We might need to separate 'move' and 'withCollsions'... into two funcs. That way we can find our two part problem, better. (#1 problem - dragging is jittery) (#2 problem - colliding is violent) Let's keep trying, eh? Interesting challenge. I KNOW it can be solved. I just need some more intelligence... and time... and comments/ideas from anyone/everyone. Quote Link to comment Share on other sites More sharing options...
Wingnut Posted May 20, 2015 Share Posted May 20, 2015 http://playground.babylonjs.com/#1P9XIK#5 new demo... I put some numbers on the screen so I could watch the drag and collision values. It's difficult to determine anything from the numbers, but I thought I'd try. *scratch scratch* I had some problems with onDispose() NOT closing old html panels. [fails to run endMenu() or endMenu() is failing to find the old html containers]. If you need to remove some old html panels that seem to be stuck on the screen, you can open a JS console and type window.endMenu() and hit enter... possibly more than once. That will remove old menus/readouts. That's all I have so far. Experts, we could use some help, here. Are there any around? This thing is starting to get over-my-head. Maybe there is some kind of solution ... using intersectsMesh. Still testing and experimenting. moveWithCollisions hates me. :/ Quote Link to comment Share on other sites More sharing options...
Wingnut Posted May 29, 2015 Share Posted May 29, 2015 Hi again! Yet another... http://playground.babylonjs.com/#BJVUV#1 This one is working ok. Drag is MUCH nicer, now, and collision ellipsoids are being honored nicely. Notice that EACH of the 4 mesh... needed to be pushed into the collidables[] array (line 43 is one such line). Collidables is used later... in onPointerMove... to set intersectionEnter triggers... so don't forget to push your mesh into that (when you make more mesh in your project). Follow the pattern of making each mesh... seen in the demo... and all will be fine. The SPEED that you collide... matters. You CAN overlap these mesh... if you collide fast enough (or if you do a 2nd overlap attempt - see below). I did a LITTLE experimenting with a variable called 'margin'. Make that number larger, and the collisions SHOULD happen with some space between the two mesh. Make it smaller, and the mesh SHOULD be allowed to get closer... and maybe overlap. This uses a dirty for-loop iteration through collidables array... adding an intersectionEnter trigger/action to every mesh in that array. (except itself) It's a crappy way to do it. It would be real nice if parameter: in line 150... were allowed to be a whole array of meshes. But it must be one mesh... so we must loop. Every time there is a collision, the test() function runs, which just force-calls onPointerUp()... which stops the drag. Kind of simple... yet miserable. The test() function should be removed from onPointerMove() and put somewhere more "global" (out in mainline code, not inside a function where it keeps getting repeatedly redefined). Hey, I make mistakes sometimes. One "feature" can be seen. Drag an object to collision point... it stops. Now continue to drag it, and you CAN overlap. So, first drag, can't overlap. Second drag, CAN overlap! Strange, huh? Remember in an earlier post... I talked about the need to "back-away" the colliding mesh... after the collision? Our demo is not doing that, and that's what MIGHT cause the "2nd drag allows overlap" feature/bug. Anyway, best demo try so far, eh? Phew... gruesome challenge. Party on! Quote Link to comment Share on other sites More sharing options...
auduct Posted May 29, 2015 Author Share Posted May 29, 2015 Thanks for this update. I got another small issue when i further customized the code. I have loaded the blender models online in this code instead of cubes and spheres.you can see live demo here: http://websorce.com/a_beta/3droom/ I have loaded it to the server because i not know if external models can be loaded in playground. These models are colliding with the objects already there but are merging inside another models. I am also attaching the code with models in the attachment. #1. The models are merging in each other as you can see these tables and/or chairs. #2. The table model is visible in localhost but is not visible when being loaded on online server. I have checked it from different browsers. the chair model is visible. model_issue.zip Wingnut 1 Quote Link to comment Share on other sites More sharing options...
Wingnut Posted May 29, 2015 Share Posted May 29, 2015 Hi collidables.push(m1); is wrong, twice. It should be... collidables.push(m); (all three times) I'm not sure WHY your table is failing to import... sometimes. Maybe insert some alerts or console.log reports...BABYLON.SceneLoader.ImportMesh("", "arch-chair/", "tablef8.babylon", scene, function (meshes) { var m = meshes[0]; console.log(m); // check to see if the object was imported m.isVisible = true; m.scaling = new BABYLON.Vector3(1,1,1); m.position.x = 0; m.position.y = 0; m.ellipsoid.scale(margin); m.showBoundingBox = showBounds; collidables.push(m);});Good luck. Quote Link to comment Share on other sites More sharing options...
auduct Posted May 29, 2015 Author Share Posted May 29, 2015 I tried the with collidables.push(m); but its still not working. Is there any way you think you can help? I mean if i send you the server access or in case playground supports model imports? or any other way? Quote Link to comment Share on other sites More sharing options...
Wingnut Posted May 30, 2015 Share Posted May 30, 2015 HiWould you please update the online version. http://websorce.com/a_beta/3droom/ I still see (m1) in there. I wish I could spend more time on this... but real life has got me running around like crazy, lately.\ All I can do is try... when I have time. Please make sure your zip file has the MOST RECENT version of the .babylon file. I will DL it later today. YOU need to keep experimenting, too. The chairs are working pretty good, already. They are not allowed to overlap our four basic shapes. I think I know what the problem is. Don't use 'm' at all. Use 'chair1' and 'chair2' and 'table1' (etc) for your variable names. Even though 'm' is being pushed into collidables[], I think we keep over-writing it when we re-assign 'm' repeatedly. Good luck, report back. Quote Link to comment Share on other sites More sharing options...
auduct Posted May 30, 2015 Author Share Posted May 30, 2015 Thanks, they started colliding too. what you think can be done to increase the performance of the models regarding collision.I have updated the code on the online link Wingnut 1 Quote Link to comment Share on other sites More sharing options...
Wingnut Posted May 30, 2015 Share Posted May 30, 2015 A quick note: Take a look at some BJS framework code... with me: https://github.com/BabylonJS/Babylon.js/blob/master/Babylon/Mesh/babylon.abstractMesh.js#L49 AbstractMesh is the basis of all BJS mesh. See that a mesh.ellipsoid is .5 units long and .5 units wide and 1.0 units tall, by default. That might be important when setting margin. Now let's look 2 lines below... anymesh._collider = new BABYLON.Collider(); SO now let's go look at Collider... https://github.com/BabylonJS/Babylon.js/blob/master/Babylon/Collisions/babylon.collider.js#L43 See that it has a .radius property? It is set 1,1,1. So... MAYBE... to set a 'margin', a person should do: anymesh._collider.radius = new BABYLON.Vector3(margin, 1, margin); (or something like that). Experiment. Maybe my old way of doing margin... is wrong. *shrug* More soon... maybe. Quote Link to comment Share on other sites More sharing options...
Wingnut Posted June 2, 2015 Share Posted June 2, 2015 Hey Auduct... I just thought about something important.... Please view: http://playground.babylonjs.com/#BJVUV#1 First, lines 144-149 should be used... if you can. That section checks to see if there is already an actionManager on the currentMesh. You might already be using that. It's just a good idea... but maybe not necessary. Programming etiquette, ya know? MOST IMPORTANT: See line 151 - collidables.remove(currentMesh); I think we should probably re-push currentMesh... into collidables[]... at the end of the onPointerMove() function. SO maybe... about line 160 area... add collidables.push(currentMesh); That way, we ONLY remove currentMesh for the FOR-loop, and then immediately push it back into collidables. Test and experiment, when you have a moment. thx! This MIGHT eliminate the "drag once more = CAN-overlap" situation. PS: Have you thought about control-z/undo? Near your new line 160... you could also add lines such as... scene.lastMovedMesh = currentMesh; scene.lastMovedMeshStartingPoint = startingPoint; These properties can later be used in an onUndo() function. Only one level of undo, but hey, not bad. 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.