Jump to content

problem applying collider


auduct
 Share

Recommended Posts

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 amount
light.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

post-14464-0-69697400-1431520748.png

Link to comment
Share on other sites

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!!!  :)

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.  :)

Link to comment
Share on other sites

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.  :D  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.

Link to comment
Share on other sites

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.  :/

Link to comment
Share on other sites

  • 2 weeks later...

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!

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

Hi

Would 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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.  :)

Link to comment
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...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...