예제 #1
0
        static void Main(string[] args)
        {
            // supplying a custom error handler to SDK initialisation

            // note that a simple messagebox error handler will be supplied, by default
            // but you should probably provide a custom error callback that interfaces directly with application side error reporting and logging functionality
            // this example code shows how to implement a custom error callback that directs error information to console output

            PathEngine.PathEngine pathEngine = DLLManagement.loadDLL("PathEngine", new ConsoleErrorHandler());

            // querying SDK version attributes

            {
                int major, minor, internalRelease;
                pathEngine.getReleaseNumbers(out major, out minor, out internalRelease);
                Console.WriteLine("getReleaseNumbers returns {0}.{1}.{2}", major, minor, internalRelease);
            }

            String[] versionAttributes = pathEngine.getVersionAttributes();
            Console.WriteLine("version attributes:");
            for (int i = 0; i < versionAttributes.Length; i += 2)
            {
                Console.WriteLine("{0} = {1}", versionAttributes[i], versionAttributes[i + 1]);
            }
            Console.WriteLine("(end of version attributes)");

            // provoke a non fatal error, and null object return

            // The error handling philosophy in PathEngine is that code should be set up so that errors should not occur,
            // so the API provides methods to validate data where relevant, and where data is validated correctly you shouldn't see any errors.

            int[] shapeCoords = { -10, -10, -10, 10, 10, 10, 10, -10 };
            shapeCoords[0] = 100; // bad coordinate

            bool valid = pathEngine.shapeIsValid(shapeCoords);

            Console.WriteLine("shapeIsValid returns {0}", valid);

            // The following call to newShape() is not considered good coding practice, then.
            // Instead application code should use shapeIsValid() (as above) to ensure that newShape() isn't called with bad coordinates.
            // But we use this here to provoke a 'NonFatal' error, so that we can see this being passed to the application side error handler.
            // In this case PathEngine will handle the error gracefully, and you should get an error posted to the supplied error handler callback, and a null object returned,
            // but in other cases, PathEngine may emit 'Fatal' errors on invalid data, and then crash after the error callback returns!

            Shape shape = pathEngine.newShape(shapeCoords); // will generate a NonFatal Error

            Console.WriteLine("shape.isNull() returns {0}", shape.isNull());

            shapeCoords[0] = -10; // fix the bad coordinate
            Console.WriteLine("(coordinates fixed)");

            valid = pathEngine.shapeIsValid(shapeCoords);
            Console.WriteLine("shapeIsValid returns {0}", valid);

            shape = pathEngine.newShape(shapeCoords);
            Console.WriteLine("shape.isNull() returns {0}", shape.isNull());

            // using the FaceVertexMesh callback to generate a simple square ground mesh

            FaceVertexMesh[] contentMeshes = new FaceVertexMesh[1];
            contentMeshes[0] = new SquareMesh();
            Mesh mesh = pathEngine.buildMeshFromContent(contentMeshes, new String[0]);

            Console.WriteLine("mesh built from content, getNumberOf3DFaces returns {0}", mesh.getNumberOf3DFaces());

            // this time we generate unobstructed space preprocess only
            // (this enables collision queries for the agent shape, pathfind preprocess is not required for the following)

            mesh.generateUnobstructedSpaceFor(shape, false, new String[0]);

            // place an agent and add to a collision context

            Position         pos         = mesh.generateRandomPosition();
            Agent            placedAgent = mesh.placeAgent(shape, pos);
            CollisionContext context     = mesh.newContext();

            context.addAgent(placedAgent);
            Console.WriteLine("context getNumberOfAgents() returns {0}", context.getNumberOfAgents());

            // call getAllAgentsOverlapped
            // (this shows the linkage for an array out argument, and also gives as another handle to compare to placedAgent)

            Agent[] overlapped;
            mesh.getAllAgentsOverlapped(shape, context, pos, out overlapped);
            Console.WriteLine("number of agents overlapped = {0}", overlapped.Length);

            // we can't compare interface object handles directly, but a getComparisonToken() method is supplied for this purpose
            // (and can also be used for sorting, if this is required)

            Console.WriteLine("placedAgent.getComparisonToken() returns {0}", placedAgent.getComparisonToken());
            foreach (Agent overlappedAgent in overlapped)
            {
                Console.WriteLine("overlappedAgent.getComparisonToken() returns {0}", overlappedAgent.getComparisonToken());
            }

            // a simple file output stream callback is supplied

            OutputStream os = new FileOutputStream("savedMesh.xml");

            mesh.saveGround("xml", false, os);

            // object lifetime notes

            {
                Mesh mesh2 = pathEngine.buildMeshFromContent(contentMeshes, new String[0]);
                // ** PathEngine interface objects are not garbage collected, so mesh2 will not be cleaned up automatically
                // ** and will therefore now be leaked, unless pathEngine.deleteAllObjects() is called
            }
            mesh.destroy(); // clean up this interface object explicitly
            // ** but don't forget that the interface object is now no longer valid, and methods should not be called on this object
            // ** and note that dependant objects such as placed agents and collision contexts are also destroyed with the mesh
            pathEngine.deleteAllObjects(); // cleans up all objects created by PathEngine

            Console.WriteLine("(completed, press enter)");
            Console.ReadLine();
        }
예제 #2
0
        static void Main(string[] args)
        {
            PathEngine.PathEngine pathEngine = DLLManagement.loadDLL("PathEngine");

            // load a ground mesh

            byte[]   meshBuffer     = System.IO.File.ReadAllBytes("../resource/meshes/mesh1.xml");
            string[] loadingOptions = {};
            Mesh     mesh           = pathEngine.loadMeshFromBuffer("xml", meshBuffer, loadingOptions);

            // create a pathfinding agent shape

            Shape shape;

            {
                int[] coordinateData = { -10, -10, -10, 10, 10, 10, 10, -10 };
                shape = pathEngine.newShape(coordinateData);
            }

            // generate preprocess for this agent shape

            string[] noOptions = { };
            mesh.generateUnobstructedSpaceFor(shape, true, noOptions);
            mesh.generatePathfindPreprocessFor(shape, noOptions);

            // generate random unobstructed positions for query start and end

            // collision contexts provide dynamic state
            // default constructed API object references act like null pointers to API objects in the native mapping
            // and null collision context arguments are used in the API to indicate no dynamic state
            CollisionContext nullContext;
            Position         start;

            do
            {
                start = mesh.generateRandomPosition();
            }while(mesh.testPointCollision(shape, nullContext, start));
            Console.WriteLine("start: {0}:{1},{2})", start.cell, start.x, start.y);
            Position goal;

            do
            {
                goal = mesh.generateRandomPosition();
            }while(mesh.testPointCollision(shape, nullContext, goal));
            Console.WriteLine("goal: {0}:{1},{2})", goal.cell, goal.x, goal.y);

            // pathfind!

            Path path = mesh.findShortestPath(shape, nullContext, start, goal);

            if (path.isNull())
            {
                Console.WriteLine("No unobstructed path exists between start and goal.");
            }
            else
            {
                Console.WriteLine("Path found with {0} points:", path.size());
                for (int i = 0; i < path.size(); ++i)
                {
                    Position p = path.position(i);
                    Console.WriteLine("{0}:{1},{2}", p.cell, p.x, p.y);
                }
            }

            Console.WriteLine("(completed, press enter)");
            Console.ReadLine();
        }