Create different camera modes in the 3D world-write a custom content importer

Source: Internet
Author: User
2.14 writing a custom content importer

You want to import a custom file to the xNa project through the content pipeline. Because the extension and/or structure of your file are different from the file formats supported by xNa, the default xNa content pipeline cannot know how to import and process your file.

Solution

You need to write a custom content importer that can read files from the disk, format useful data into an object, and prepare for processing by the content processor. Therefore, this tutorial assumes that you know how to create your own content processor. For more information, see tutorial 3-9.

This tutorial only cares about the Custom Import tool. Contentionmporter needs to read data from the disk and format it as an object. In this tutorial, you need to read two vector3 files stored in a common-separated values (CSV file) file separated by commas and convert them into a matrix. The reason for selecting this example is that a view matrix needs to be computed before it can be built. xNa has a default typewriter and typereader that can serialize and deserialize matrix objects, in this tutorial, you can only focus on loading files from the disk, writing the content importer, and obtaining data from the custom content processor.

Take a look at 2-27. The custom importer reads data from a CSV file and creates a csvimportertoprocessor object to store useful data obtained from the file. Custom csvmatrixprocessor processes data in the csvimportertoprocessor object and saves it to a matrix object. XNa then serializes and deserializes matrix typewriter and typereader by default. See tutorials 4-15 and 4-16 to learn how to write your own typewriter and typereader.

Because both the importer and processor are called during compilation, you may want to know the benefits of separating the importer and processor. For example, why cannot I simply define only one method to read a CSV file and store it in a matrix object immediately instead of writing two methods and an intermediate csvmatrixprocessor object?

The advantage of separating the processing process is that you can reuse the processor for multiple import devices (and vice versa ). For example, the xNa framework can convert a nodecontent object to a modelcontent object. If you do not. X or. to import a model to a file in fbx format, you must compile an importer to create a nodecontent object for your file. Then you can use the default modelprocessor.

Figure 2-27 define a content importer and its location in the content Pipeline

Working Principle

First, use a text editor to create a CSV file. below is my CSV file:

 
-5; 5; 8; 0; 2; 0;

These are the observation targets of the position of the visual matrix that will be built in the tutorial.

Csvimportertoprocessor class

Next, let's take a look at the step list in 3-9 of the tutorial. I call my own content pipeline project csvtoviewmatrixplpeline. Do not perform any operations in step 3-9 of the tutorial. You need to write some additional methods. At the end of this tutorial, you can see allCode.

First, you need an object to store the data read from the disk. This object serves as the output and processor input of the import tool (this will use its content to build a matrix of views ). Add a custom csvimportertoprocessor class, which stores two vectors:

Public class csvimportertoprocessor {private vector3 position; private vector3 target; Public vector3 position... {get... {return position ;}} public vector3 target... {get... {return target ;}} public csvimportertoprocessor (vector3 position, vector3 target) {This. position = position; this.tar get = target ;}}

This class can store two vectors3. The two getter methods allow the processor to access this data. When calling the constructor, the importer needs to provide all the data.

Contentimporter

Contentimporter is used to read data from the file, so make sure that the namespace containing the data has been added to the top of the file (see step 3rd in tutorial 3-9 ):

 
Using system. IO;

Prepare for writing the Custom Import, and add the following code:

 
[Contentimporter (". CSV", defaultprocessor = "csvmatrixprocessor")] public class csvimporter: contentimporter <strong> {public override writable import (string filename, contentimportercontext context ){}}

The first-line example can be used to process the .csv file, and its output is processed by csvmatrixprocessor by default (which will be created below ). In the following code, you specify that the importer will generate a csvimportertoprocessor object.

During compilation, the import tool imports a. CSV file and converts it to a csvimportertoprocessor object. First open the file to read the first line, which is carried out in the first two lines of the following code. To split; between values, you need to use a simple split method, this will return an array of three strings, each string contains the number of the camera position, the next three lines of code convert these three strings into floating-point numbers to create the final position vector3.

 
Streamreader file = new streamreader (filename); string line = file. readline (); string [] linedata = line. split (';'); float x = float. parse (linedata [0]); float y = float. parse (linedata [1]); float z = float. parse (linedata [2]); vector3 position = new vector3 (x, y, z );

Read the second line from the file, use the same method, and convert it to an observation target vector3:

 
Line = file. readline (); linedata = line. split (';'); X = float. parse (linedata [0]); y = float. parse (linedata [1]); Z = float. parse (linedata [2]); vector3 target = new vector3 (x, y, z );

Now, you can create a csvimportertoprocessor object with data:

Csvimportertoprocessor finaldata = new csvimportertoprocessor (Position, target); Return finaldata;

This object is sent to the user-selected processor. Obviously, the processor should be able to use the csvimportertoprocessor object as the input.

Accept data in a content Processor

Because the csvimportertoprocessor class is a custom class, you need to create a custom processor. This processor converts a csvimportertoprocessor object to a matrix object. Let's take a look at the first tutorial in this chapter to learn how to build a visual matrix based on the camera position and observation target:

 
[Contentprocessor] public class csvmatrixprocessor: contentprocessor <csvimportertoprocessor, matrix> {public override matrix process (partition input, contentprocessorcontext context) {vector3 up = new vector3 (0, 1, 0 ); vector3 forward = input. target-input. position; vector3 right = vector3.cross (forward, up); up = vector3.cross (right, forward); matrix viewmatrix = matrix. createlookat (input. position, input. target, up); Return viewmatrix ;}}

You declare that this processor can convert a csvimportertoprocessor object to a matrix object. Position and target in the csvimportertoprocessor object are used to create the view matrix. XNa knows how to serialize/deserialize a matrix object from a binary file and load the matrix object to an xNa project. Therefore, you do not need to write custom typewriter and typereader.

Usage

After confirming that you have completed 9 steps in the tutorial 3-9, you can import the .csv file to the project. When selecting a .csv file in the resolution resource manager, you should be able to note in the Properties window that this file is imported by csvimporter, as shown in 2-28, Because you declare csvimporter as the default importer and csvmatrixprocessor as the processor.

Figure 2-28 select the content importer and processor

After importing the .csvfile, you must use the following code to load an image matrix from the. CSV file:

 
Protected override void loadcontent () {viewmatrix = content. Load <matrix> ("camerasettings ");}
Code

because the content pipeline is short, I put it together. The first code block is the namespace. The first class in the namespace is the csvimportertoprocessor class, which can store all the data. The contentimporterclass is used to read and store datasets in the csvimportertoprocessor object from a. CSV file. The final code block is a content processor. You can build an object matrix based on the content in the csvimportertoprocessor object. Because xNa comes with typewriter and typereader that can process matrix objects, the above Code is a complete functional content pipeline. If your processor creates a custom Class Object, see tutorials 4-15 and 4-16 to learn how to create your own typewriter and typereader.

Using system; using system. collections. generic; using system. LINQ; using Microsoft. xNa. framework; using Microsoft. xNa. framework. graphics; using Microsoft. xNa. framework. content. pipeline; using Microsoft. xNa. framework. content. pipeline. graphics; using Microsoft. xNa. framework. content. pipeline. processors; using system. io; using Microsoft. xNa. framework. content; using Microsoft. xNa. framework. content. pipeline. serialization. compiler; namespace cvstoviewmatrixpipeline {public class csvimportertoprocessor {private vector3 position; private vector3 target; Public vector3 position... {get... {return position ;}} public vector3 target... {get... {return target ;}} public csvimportertoprocessor (vector3 position, vector3 target) {This. position = position; this.tar get = target;} [contentimporter (". CSV ", defaultprocessor =" csvmatrixprocessor ")] public class csvimporter: contentimporter <character> {public override writable import (string filename, contentimportercontext context) {streamreader file = new streamreader (filename ); string line = file. readline (); string [] linedata = line. split (';'); float x = float. parse (linedata [0]); float y = float. parse (linedata [1]); float z = float. parse (linedata [2]); vector3 position = new vector3 (x, y, z); line = file. readline (); linedata = line. split (';'); X = float. parse (linedata [0]); y = float. parse (linedata [1]); Z = float. parse (linedata [2]); vector3 target = new vector3 (x, y, z); csvimportertoprocessor finaldata = new csvimportertoprocessor (Position, target); Return finaldata ;}} [contentprocessor] public class csvmatrixprocessor: contentprocessor <csvimportertoprocessor, matrix> {public override matrix process (partition input, contentprocessorcontext context) {vector3 up = new vector3 (0, 1, 0 ); vector3 forward = input. target-input. position; vector3 right = vector3.cross (forward, up); up = vector3.cross (right, forward); matrix viewmatrix = matrix. createlookat (input. position, input. target, up); Return viewmatrix ;}}}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.