Jump to content

Should I first call scene.render before making any pickWithRay calls?


Recommended Posts

Thank you @Sebavan for your support.

My scene is an apartment. I need implement a functionality that the camera should go thru all the rooms . For this we need to findout obstacles.

My algorithm in a nutshell.

 

Phase 1:

1. for each mesh which is a floor, do a clipping. (As I dont know how to do it, I am calculating boundingBox  and taking points)   

2. for each point, fire a ray upwards at a distance of camera height.

2.1) If it wont touch any mesh, it means there is no object on the floor or there is no object hanging below camera height from the roof or wall. -- then add it into a points array. (These will be vertices for my graph)

 

Phase 2:

1.  for each point from this array check with every other point if it is its neighbour. 

1.2 If it is a neighbour, then fire a ray towards this point. If the ray wont touch any mesh, then there is no obstacle (like a wall) between these two points, add an edge in the graph.

 

Navigator.prototype._calculateAndUpdateNavigablePointsAndBuildGraph = function () {
            var _this = this;
            var cameraHeight = _this._cameraHeight;
            var walkableIdentificationStrategy = _this._walkableIdentificationStrategy;
            var strideLength = _this._strideLength;
            var scene = _this._scene;
        
            var direction = new BABYLON.Vector3(0, 1, 0);
            var navigablePoints = [];

            scene.meshes.forEach(m => {
                m.computeWorldMatrix(true);
            });

 

//Phase 1

            scene.meshes.forEach(mesh => {
                if (walkableIdentificationStrategy(mesh)) {
                    var boundingBox = mesh.getBoundingInfo().boundingBox;

                    var min = boundingBox.minimumWorld;
                    var max = boundingBox.maximumWorld;
                    for (var x = min.x + (strideLength / 2); x <= max.x - (strideLength/2); x += strideLength) {
                        for (var z = min.z + (strideLength / 2); z <= max.z - (strideLength / 2); z += strideLength) {
                            var p = new BABYLON.Vector3(x, max.y, z);
                            var ray = new BABYLON.Ray(p, direction, cameraHeight);
                            var hit = scene.pickWithRay(ray, m => {
                                if (!m.isVisible) {
                                    return false;
                                }
                                if (m === mesh) {
                                    return false;
                                }
                                if (walkableIdentificationStrategy(m)) {
                                    return false;
                                }
                                return true;
                            });

                            if (!hit.pickedMesh) {
                                var pointAtCameraHeight = new BABYLON.Vector3(p.x, p.y + cameraHeight, p.z);
                                navigablePoints.push(pointAtCameraHeight);
                            } 
                        }
                    }
                }
            });

            
            var indexDictionary = buckets.Dictionary(key => {
                return key.toString();
            });
            

//Phase 2

            var strideLengthDiagonal = Math.sqrt(2) * strideLength;
            var graph = new jsgraphs.WeightedDiGraph(navigablePoints.length);
            //var edgesCount = 0;
            for (var i = 0; i < navigablePoints.length; i++) {
                var pi = navigablePoints;
                indexDictionary.set(i, pi);
                
                for (var j = i + 1; j < navigablePoints.length; j++) {
                    var pj = navigablePoints[j];

                    var distance = BABYLON.Vector3.Distance(pi, pj);
                    if (distance <= strideLengthDiagonal) {
                        var forwardRay = new BABYLON.Ray(pi, pj.subtract(pi), distance);
                        var forwardHit = scene.pickWithRay(forwardRay, m => {
                            if (!m.isVisible) {
                                return false;
                            }
                            //if (m.name === "ray") {
                            //    return false;
                            //}
                            return true;
                        });

                        if (!forwardHit.pickedMesh) {
                            graph.addEdge(new jsgraphs.Edge(i, j, distance));
                            graph.addEdge(new jsgraphs.Edge(j, i, distance));
                            //edgesCount++;
                            //var rayHelper = new BABYLON.RayHelper(forwardRay);
                            //rayHelper.show(_this._scene);
                            //console.log(i + "," + j);
                            //var lines = BABYLON.MeshBuilder.CreateLines("lines", { points: [pi, pj] }, scene);
                        }
                    }
                }
            }

            //navigablePoints.forEach(p => {
            //    var s = BABYLON.Mesh.CreateSphere("", 16, 0.1, scene);
            //    s.position = p;
            //});

            _this._navigablePoints = navigablePoints;
            _this._indexDictionary = indexDictionary;
            _this._graph = graph;

        };

Link to post
Share on other sites

I don't know if I can achieve this functionality with the built-in collision.

for my model, when it is loaded, I do

1. for each floor mesh, for each of its facet, get the facet position and keep it in an array

 2. In my UI, there is a button "Tour".  When the user clicks this button, I need to animate camera to all these points. 

If the user is in kitchen and clicks on tour, then I need to plan my tour from that point. We need to use shortest path algorithms like Dijkstra/ Bellman-Ford  and Travelling Salesman.

 

Link to post
Share on other sites

I have many questions. To start with

1. Have you designed and created the apartment? Or

2. Are you importing an apartment somebody else created?

3. Are the obstacles in a fixed position?

4. When at point A in the apartment do you know where the obstacles are?

 

 

 

Link to post
Share on other sites
On 11/27/2018 at 12:27 AM, JohnK said:

I have many questions. To start with

1. Have you designed and created the apartment?  - YES

2. Are you importing an apartment somebody else created? - NO

3. Are the obstacles in a fixed position? - YES

4. When at point A in the apartment do you know where the obstacles are? - As obstacles are fixed, i think yes 

 

 

 

Hi @JohnK,

My answers are inline

 

Link to post
Share on other sites

JustYou know the network of room connections. For example 

A to B, B to C|D, C to E, D to F, E to F so you can work out the shortest path from room to room. When you are in a room A at point P and you want to get to room E then you need to get to the correct door (A1) of A that will lead to room E eventually. In room A your path is from P to door A1 avoiding obstacles. From door A1 you need to pass through room B to door B1 avoiding obstacles in room B and so on.

There are two distinct stages, you need to know how to move within any room and avoid obstacles plus know the sequence of rooms to visit to get from start room to end room.

Does the above give a description of what you want to do?

 

Link to post
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...
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...