Esempio n. 1
0
        public override void Dispose()
        {
            mRay.Dispose();
            mRay = null;

            mRaySceneQuery.Dispose();
            mRaySceneQuery = null;

            /*if (myLine != null)
             * {
             *      SceneNode n = mSceneManager.GetSceneNode("Line1");
             *      if (n!= null)
             *              n.DetachObject(myLine);
             *      myLine.Dispose();
             * }*/
            myLine.Dispose();
            myLine = null;

            mLog.Dispose();
            mLog = null;

            base.Dispose();
        }
        public float GetTSMHeightAt(float x, float z)
        {
            float y = 0.0f;

            Ray updateRay = new Ray();

            updateRay.Origin    = new Vector3(x, 9999, z);
            updateRay.Direction = Vector3.NEGATIVE_UNIT_Y;

            RaySceneQuery tsmRaySceneQuery = this.sceneMgr.CreateRayQuery(updateRay);

            RaySceneQueryResult qryResult = tsmRaySceneQuery.Execute();

            RaySceneQueryResult.Iterator i = qryResult.Begin();
            if (i != qryResult.End() && i.Value.worldFragment != null)
            {
                y = i.Value.worldFragment.singleIntersection.y;
            }

            this.sceneMgr.DestroyQuery(tsmRaySceneQuery);
            tsmRaySceneQuery.Dispose();

            return(y);
        }
        public RaycastResult Raycast(Ray ray, uint queryMask)
        {
            RaycastResult rr = new RaycastResult();

            RaySceneQuery raySceneQuery = this.sceneMgr.CreateRayQuery(new Ray());

            raySceneQuery.SetSortByDistance(true);

            // check we are initialised
            if (raySceneQuery != null)
            {
                // create a query object
                raySceneQuery.Ray = ray;
                raySceneQuery.SetSortByDistance(true);
                raySceneQuery.QueryMask = queryMask;

                // execute the query, returns a vector of hits
                if (raySceneQuery.Execute().Count <= 0)
                {
                    // raycast did not hit an objects bounding box
                    return(null);
                }
            }
            else
            {
                // LogManager.Singleton.LogMessage("Cannot raycast without RaySceneQuery instance");
                return(null);
            }

            // at this point we have raycast to a series of different objects bounding boxes.
            // we need to test these different objects to see which is the first polygon hit.
            // there are some minor optimizations (distance based) that mean we wont have to
            // check all of the objects most of the time, but the worst case scenario is that
            // we need to test every triangle of every object.
            // Ogre::Real closest_distance = -1.0f;
            rr.Distance = -1.0f;
            Vector3             closest_result = Vector3.ZERO;
            RaySceneQueryResult query_result   = raySceneQuery.GetLastResults();

            for (int qridx = 0; qridx < query_result.Count; qridx++)
            {
                // stop checking if we have found a raycast hit that is closer
                // than all remaining entities
                if ((rr.Distance >= 0.0f) && (rr.Distance < query_result[qridx].distance))
                {
                    break;
                }

                // only check this result if its a hit against an entity
                if ((query_result[qridx].movable != null) &&
                    (query_result[qridx].movable.MovableType.CompareTo("Entity") == 0))
                {
                    // get the entity to check
                    Entity pentity = (Entity)query_result[qridx].movable;

                    // mesh data to retrieve
                    uint      vertex_count;
                    uint      index_count;
                    Vector3[] vertices;
                    ulong[]   indices;

                    // get the mesh information
                    GetMeshInformation(
                        pentity.GetMesh(),
                        out vertex_count,
                        out vertices,
                        out index_count,
                        out indices,
                        pentity.ParentNode._getDerivedPosition(),
                        pentity.ParentNode._getDerivedOrientation(),
                        pentity.ParentNode.GetScale());

                    // test for hitting individual triangles on the mesh
                    bool new_closest_found = false;
                    for (int i = 0; i < (int)index_count; i += 3)
                    {
                        // check for a hit against this triangle
                        Pair <bool, float> hit = Mogre.Math.Intersects(ray, vertices[indices[i]], vertices[indices[i + 1]], vertices[indices[i + 2]], true, false);

                        // if it was a hit check if its the closest
                        if (hit.first)
                        {
                            if ((rr.Distance < 0.0f) ||
                                (hit.second < rr.Distance))
                            {
                                // this is the closest so far, save it off
                                rr.Distance       = hit.second;
                                new_closest_found = true;
                            }
                        }
                    }

                    // if we found a new closest raycast for this object, update the
                    // closest_result before moving on to the next object.
                    if (new_closest_found)
                    {
                        rr.Target      = pentity;
                        closest_result = ray.GetPoint(rr.Distance);
                    }
                }
            }

            this.sceneMgr.DestroyQuery(raySceneQuery);
            raySceneQuery.Dispose();

            // return the result
            if (rr.Distance >= 0.0f)
            {
                // raycast success
                rr.Position = closest_result;
                return(rr);
            }
            else
            {
                return(null);
            }
        }
Esempio n. 4
0
        public RaycastResult Raycast(Ray ray, uint queryMask)
        {
            RaycastResult rr = new RaycastResult();

            RaySceneQuery raySceneQuery = this.sceneMgr.CreateRayQuery(new Ray());

            raySceneQuery.SetSortByDistance(true);

            // check we are initialised
            if (raySceneQuery != null)
            {
                // create a query object
                raySceneQuery.Ray = ray;
                raySceneQuery.SetSortByDistance(true);
                raySceneQuery.QueryMask = queryMask;

                using (RaySceneQueryResult queryResult = raySceneQuery.Execute())
                {
                    // execute the query, returns a vector of hits
                    if (queryResult.Count <= 0)
                    {
                        // raycast did not hit an objects bounding box
                        this.sceneMgr.DestroyQuery(raySceneQuery);
                        raySceneQuery.Dispose();
                        return(null);
                    }

                    // at this point we have raycast to a series of different objects bounding boxes.
                    // we need to test these different objects to see which is the first polygon hit.
                    // there are some minor optimizations (distance based) that mean we wont have to
                    // check all of the objects most of the time, but the worst case scenario is that
                    // we need to test every triangle of every object.
                    // Ogre::Real closest_distance = -1.0f;
                    rr.Distance = -1.0f;
                    Vector3 closestResult = Vector3.ZERO;

                    for (int qridx = 0; qridx < queryResult.Count; qridx++)
                    {
                        // stop checking if we have found a raycast hit that is closer
                        // than all remaining entities
                        if (rr.Distance >= 0.0f && rr.Distance < queryResult[qridx].distance)
                        {
                            break;
                        }

                        // only check this result if its a hit against an entity
                        if (queryResult[qridx].movable != null &&
                            queryResult[qridx].movable.MovableType == "Entity")
                        {
                            // get the entity to check
                            Entity entity = (Entity)queryResult[qridx].movable;

                            // mesh data to retrieve
                            Vector3[] vertices;
                            int[]     indices;
                            RenderOperation.OperationTypes opType;

                            // get the mesh information
                            using (MeshPtr mesh = entity.GetMesh())
                            {
                                opType = mesh.GetSubMesh(0).operationType;

                                Debug.Assert(CheckSubMeshOpType(mesh, opType));

                                GetMeshInformation(
                                    mesh,
                                    out vertices,
                                    out indices,
                                    entity.ParentNode._getDerivedPosition(),
                                    entity.ParentNode._getDerivedOrientation(),
                                    entity.ParentNode._getDerivedScale());
                            }

                            int vertexCount = vertices.Length;
                            int indexCount  = indices.Length;

                            // test for hitting individual triangles on the mesh
                            bool newClosestFound = false;
                            Pair <bool, float> hit;
                            switch (opType)
                            {
                            case RenderOperation.OperationTypes.OT_TRIANGLE_LIST:
                                for (int i = 0; i < indexCount; i += 3)
                                {
                                    hit = Mogre.Math.Intersects(ray, vertices[indices[i]], vertices[indices[i + 1]], vertices[indices[i + 2]], true, false);

                                    if (CheckDistance(rr, hit))
                                    {
                                        newClosestFound = true;
                                    }
                                }
                                break;

                            case RenderOperation.OperationTypes.OT_TRIANGLE_STRIP:
                                for (int i = 0; i < indexCount - 2; i++)
                                {
                                    hit = Mogre.Math.Intersects(ray, vertices[indices[i]], vertices[indices[i + 1]], vertices[indices[i + 2]], true, true);

                                    if (CheckDistance(rr, hit))
                                    {
                                        newClosestFound = true;
                                    }
                                }
                                break;

                            case RenderOperation.OperationTypes.OT_TRIANGLE_FAN:
                                for (int i = 0; i < indexCount - 2; i++)
                                {
                                    hit = Mogre.Math.Intersects(ray, vertices[indices[0]], vertices[indices[i + 1]], vertices[indices[i + 2]], true, true);

                                    if (CheckDistance(rr, hit))
                                    {
                                        newClosestFound = true;
                                    }
                                }
                                break;

                            default:
                                throw new Exception("invalid operation type");
                            }

                            // if we found a new closest raycast for this object, update the
                            // closest_result before moving on to the next object.
                            if (newClosestFound)
                            {
                                rr.Target     = entity;
                                closestResult = ray.GetPoint(rr.Distance);
                            }
                        }
                    }

                    this.sceneMgr.DestroyQuery(raySceneQuery);
                    raySceneQuery.Dispose();

                    // return the result
                    if (rr.Distance >= 0.0f)
                    {
                        // raycast success
                        rr.Position = closestResult;
                        return(rr);
                    }
                    else
                    {
                        return(null);
                    }
                }
            }
            else
            {
                return(null);
            }
        }