Пример #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
 /// <summary>Adds another mesh to this instance of a mesh.</summary>
 /// <param name="mesh">The mesh to add.</param>
 public void Add(FaceVertexMesh mesh)
 {
     int vertices = this.Vertices.Length;
     int materials = this.Materials.Length;
     int faces = this.Faces.Length;
     // vertices
     Array.Resize<Vertex>(ref this.Vertices, vertices + mesh.Vertices.Length);
     for (int i = 0; i < mesh.Vertices.Length; i++) {
         this.Vertices[vertices + i] = mesh.Vertices[i];
     }
     // materials
     Array.Resize<Material>(ref this.Materials, materials + mesh.Materials.Length);
     for (int i = 0; i < mesh.Materials.Length; i++) {
         this.Materials[materials + i] = mesh.Materials[i];
     }
     // faces
     Array.Resize<Face>(ref this.Faces, faces + mesh.Faces.Length);
     for (int i = 0; i < mesh.Faces.Length; i++) {
         this.Faces[faces + i].Material = mesh.Faces[i].Material + materials;
         this.Faces[faces + i].Type = mesh.Faces[i].Type;
         this.Faces[faces + i].Vertices = new int[mesh.Faces[i].Vertices.Length];
         for (int j = 0; j < mesh.Faces[i].Vertices.Length; j++) {
             this.Faces[faces + i].Vertices[j] = mesh.Faces[i].Vertices[j] + vertices;
         }
     }
 }