Assignment Goals

The primary goals of this assignment are:

  1. Create an Unreal Editor Plugin from scratch.
  2. Create an Unreal Editor object importer.
  3. Get experience looking through other plugin code and engine source as a strategy for working with a large codebase.

For this assignment, you'll be creating an importer plugin to load a UVolumeTexture object from a file. The importer will load files in a subset of the NRRD format, created for and used by the Teem visualization toolkit. This is a simple uncompressed format supporting both image and volume files. It consists of an ASCII text header describing the file contents, coupled with an uncompressed binary array of data, either embedded in the same file (typically using the ".nrrd" extension) or in a separate file in the same directory (typically using the ".nhdr" extension). Though there is a convention that detached header files use .nhdr, the format does not distinguish between the two extensions. Similarly, there is a convention to use .raw for the binary data, but it can legally use any extension or none at all.

Volume rendering of sample volume Volume rendering of hydrogen_atom.nhdr
Sample volume Hydrogen atom

Details

This time I have created an initial assn5 project for you, including a test material and hydrogen atom electron orbitals volume file in the assn5/Data directory.

This is the contents of the hydrogen_atom.nhdr file, with an explanation of each line. Other than the first line, header lines can appear in any order.

NRRD0004 Always the first line, identifies this as a valid file using NRRD version 4
# [...] Comment lines starting with "#". Ignore
type: uint8 Data type for each element. In this case, unsigned byte
dimension: 3 2 for greyscale images, 3 for color images or 1-channel volumes, 4 for color volumes
space: left-posterior-superior For medical data, how the dimensions are oriented relative to the patient. Ignore
sizes: 128 128 128 Size in each dimension (read this from the file, do not hard code)
space directions: (1,0,0) (0,1,0) (0,0,1) Spatial directions for the dimensions. Ignore
kinds: domain domain domain Says this is a volume file with 3 spatial dimensions. Ignore unless you're doing the color file extension.
endian: little For multi-byte data, what byte order was used. Ignore unless you're doing the int16 extension.
encoding: raw Could say that the data is ascii or compressed. Ignore
space origin: (-64.0,-64.0,-64.0) Offset to center the volume. Ignore
data file: [...].raw File name in the same directory to find the data

You are writing your own nrrd/nhdr importer code for this assignment, not linking to the Teem libraries. Your importer only needs to support 1-channel volumes with unsigned byte components and the data in a separate file (like the hydrogen atom). You should ignore header lines that your importer does not support, but report errors for unsupported values in header lines you do support (e.g. if dimension is anything but 3). Also report errors for illogical or incorrect values (e.g. if any of the sizes are zero or negative). Report errors using UE_LOG with a new log category (not just LogTemp) so they will show up in the editor Output window.

This assignment provides only rough pointers to where to find examples and class declarations you will need. Part of the assignment is for you to get more comfortable searching through the source to find things like this.

I have pushed a data directory to your github repository with the hydrogen atom files to use for testing. You can find more files in the Open Scientific Visualization Datasets. To use these files, you will need to download both the nhdr and raw file. Pay attention to the data type, since there are both uint8 and uint16 files.

Get the project

  1. Do a git pull to get the project starter content.
    • You must use this as a starting point this time.
  2. Familiarize yourself with what is provided
    • There is C++ project code like assn1 to find assn5/Shaders.
    • There is a volume rendering shader in assn5/Shaders/Volume.ush.
    • There is a Volume material. You will need to change the top texture object in this material once you have your import working.
    • There are some sample data files in assn5/Data.

Create the plugin

  1. This time you will start from a Blank code plugin.
  2. Add an asset load class derived from UFactory to your plugin.
    • Add this in a new header and C++, not in the same files as the ModuleInterface file
    • Run GenerateProjectFiles and restart Visual Studio after adding the new files
    • Don't forget to add the PLUGINNAME_API macro in the class definition so it will be exported from your plugin module's dll
  3. Make your asset loader
    • To load from a file, you should override the UFactory::FactoryCreateFile function. Find examples in the engine and engine plugins.
    • To avoid undefined symbol errors, add the module for UFactory to your plugin's Build.cs. Follow the directory tree from the UFactory file to find its Build.cs file and find the module name.
    • When you do this, GenerageProjectFiles may complain that it is an Editor module, but your plugin is marked as Runtime. Change the plugin to Editor in the uplugin file.
    • Use Formats.Add in your class constructor to tell UE that you handle files with the nrrd and nhdr file extensions. Note that the code that implements Formats.Add cannot handle extra spaces before the extension, or before or after the ";" that separates the extension from description.
    • At this point, if your importer creates and returns an empty UVolumeTexture object, you should be able to drag an nhdr file into the Content window and get an empty volume texture object to confirm that your format registration code is correct.
    • Delete the old imported asset before trying to import again. Assuming you have not actually used it for anything (added it to any materials or as a property on another object), it is safe to "Force Delete" when removing the object.
  4. Load and parse the nrrd header file
    • Look at FFileHelper for file loading functions.
    • Look at FString and FCString for simple string matching and string-to-integer conversion functions.
    • I recommend reading the file by lines. A few options for parsing the lines: you could split the line into key and value at the ":", split into tokens on whitespace, or even just use sscanf
    • If things go wrong, use UE_LOG to send a message to the Editor Output window and return nullptr.
  5. Load the data
    • FPaths has some helpful functions for splitting a file name into the path, base, and extension. Since the data file resides in the same directory as the header, you will need to combine the path for the nhdr file with the data file name to get the full file path to open to read the data.
    • Load the data into the UVolumeTexture
      • Set UTexture::SRGB to 0, since this is not color data
      • Set UTexture::MipGenSettings to TextureMipGenSettings::TMGS_NoMipmaps to avoid generating multiple resolution versions of the volume data (which may fail if the dimensions are not a power of two).
      • Texture.Source.Init will initialize the size, format (e.g. TSF_G8), and data
      • Call UTexture::UpdateResource to update the UVolumeTexture object with the loaded data

Grad Students

Support at least two additional features for your importer:

Create test files for any features you add. If they are small (under 10 MB) you can commit them directly to your repository. Any larger sample files should be stored on google drive (or similar) with a link included in your assn5.txt file. The easiest way to create test files this is to write a simple standalone program to write them. You do not need to submit any data generation programs, just the resulting test data files.

Extra Credit

For up to 5 points each, add one or more of the grad features, up to a maximum of three (for up to 15 points of extra credit). Grad students must have at least two, but can get extra credit by doing more than two.

Submission

As always, for full credit, you must commit multiple times during your development.

Add an assn5.txt. Tell us what works and what doesn't, and anything else you think we should know for grading. For grad students, tell us what extensions you did. If you did any extensions for extra credit, tell us which ones (I won't grade extra credit if you don't tell me you did it!). Tell us where to find the test files for any extensions.

For the base assignment, include a screen shots of the UE editor pane for your VolumeTexture object in "Depth Slices" view mode, and a screen shot of the test volume material using your volume data.

If you did the FScopedSlowTask progress meter extension, record video of you importing your file(s) so we can see the progress meter in action. Upload the video to google drive, youtube, or similar, and include a link to it in your assn5.txt file.

Push to your repository, and tag your final commit with an assn5 tag. Make sure the images and video links are included in the commit that you tag for us to grade.