ARIA is a collection of foundational computer graphics infrastructure for research.
ARIA is a melting pot where you can find many interesting things, such as:
Property: C#-like properties.- Define a C#-like property with several lines of codes.
- Even stronger than the C# built-in features.
Array,Vector: Policy-based arrays and vectors.- Support CPU or GPU storages.
- Support automatic AoS to SoA layouts.
TensorVector: Policy-based multidimensional arrays and views.- Support CPU or GPU storages.
- Support arbitrary multidimensional layouts.
- Optimized for fully or partially compile-time-determined layouts.
- Support automatic AoS to SoA layouts.
VDB: Light-weighted and policy-based "VDB".- Much slower than
OpenVDBandNanoVDB. - Light-weighted and easy to compile.
- Support GPU storages.
- Support thread-safe memory allocations.
- Support thread-safe read and write accesses.
- Support kernel launches for each valid coordinate.
- Support infinite domains with arbitrary coordinates.
- Support automatic AoS to SoA layouts.
- Much slower than
Object,Component,Transform: Unity-like hierarchical objects.- Powered with C#-like
Propertys. - Interfaces are almost the same as Unity.
- Powered with C#-like
- Many other interesting features, see the documents in headers.
ARIA is extremely radical:
- Compiler support: Fully cross-platform but at least C++ 20 and CUDA 12.
- Usually, we have to modify several lines of codes before compiling.
- Different versions of compilers have different features (maybe bugs).
- Not that easy to bypass these issues for C++ beginners.
- Interfaces may be revised without any warnings.
- Here lists all (relatively) stable modules:
ARIA::Core::Concurrency,ARIA::Core::Core,ARIA::Core::Coroutine,ARIA::Core::Geometry,ARIA::Core::Math,ARIA::Scene::Scene.
But, we promise, ARIA adheres to strict coding standards, and we add as many comments as possible to each file, including the usage of interfaces and implementation details. So, feel free to import ARIA and use any feature you are interested in.
This tutorial shows how to integrate ARIA into a simple project with cmake and CPM.
-
Download the latest CUDA, see https://developer.nvidia.com/cuda-downloads.
(Currently, ARIA cannot compile without CUDA. We will fix it in the future.)
-
Suppose your project name is
ProjName. create the following directories and files:ProjName/ ├─ cmake/ ├─ CMakeLists.txt ├─ main.cpp
-
Copy
CPM.cmaketocmake/, see https://github.com/cpm-cmake/CPM.cmake.ProjName/ ├─ cmake/ │ ├─ CPM.cmake ├─ CMakeLists.txt ├─ main.cpp
-
Edit
CMakeLists.txt:cmake_minimum_required(VERSION 3.25.2) project(ProjName LANGUAGES CXX) list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" "${CMAKE_BINARY_DIR}") include(CPM) CPMAddPackage( NAME ARIA GITHUB_REPOSITORY Nagisaaaaaaaaa/ARIA GIT_TAG main OPTIONS "ARIA_BUILD_TESTS OFF" ) add_executable(${PROJECT_NAME} main.cpp) target_link_libraries(${PROJECT_NAME} PUBLIC ARIA::Core::Core )
-
Reload cmake.
-
Edit
main.cpp:#include <ARIA/ForEach.h> int main() { std::string s = "Hello ARIA!"; ARIA::ForEach(s.length(), [&](auto i) { fmt::print("{}", s[i]); }); fmt::print("\n"); return 0; }
-
Now, we are ready to compile the codes.
-
What is a proxy?
You may have known that
std::vector<bool>is a special case in C++ STL. See https://en.cppreference.com/w/cpp/container/vector_bool if you are not familiar with it. The signature ofoperator[]looks like this:reference operator[](size_type pos); const_reference operator[](size_type pos) const;
Anything wrong? Consider the following example:
std::vector<bool> v(1); auto x = v[0]; std::cout << x << std::endl; // 0 v[0] = true; std::cout << x << std::endl; // ?
It will print
0at the first time, easy. But, how about the second time? It will be1, not0! That is becauseautowas not deduced tobool, instead, it was deduced to "a magic reference" tobool(As STL says).In ARIA, we call this kind of reference as a proxy.
-
autois dangerous in ARIA.Many people may have told you that you should use
autoas much as possible. But as you have seen in the above example,autodoes not work well with proxies. You may argue thatstd::vector<bool>is not a common case. That's right, but, ARIA uses other proxies almost everywhere. Here lists the currently used proxies:std::vector<bool>,thrust::device_reference,Eigen,
and most importantly, ARIA has its own proxy generator system and ARIA heavily relies on it. We call it the property system (because it is very similar to the C# built-in feature with the same name). See
Property.h. -
Why property so important?
Suppose
class Transformrepresents position, rotation and scale of anObject. All game engines implement hierarchical object systems.Transformof eachObjectnot only contains itslocalPosition,localRotation, andlocalScale. It should also be able to compute for example,positionandrotation, which represent position and rotation in world coordinate.Traditionally, if we want to get or set these things, we should declare methods such as:
GetPosition,SetPosition,GetRotation, andSetRotaion. It works, but not elegant. The ARIA property system makes it able to:Object obj = ...; obj.transform().localPosition() = {1_R, 2_R, 3_R}; obj.transform().localRotation() = {1_R, 0_R, 0_R, 0_R}; // No longer need to call the redundant `SetPosition` and `SetRotation`. obj.transform().position() += {1_R, 2_R, 3_R}; obj.transform().rotation() *= {1_R, 0_R, 0_R, 0_R}; // We can even directly set their members, that is, property can be recursive. obj.transform().position().x() += 1_R; obj.transform().rotation().w() *= 2_R;We can use
position(),rotation,position().x(), androtation.w()as if these functions return references to the underlying member variables, but actually, these variables do not exist. Now, we are able to write C#-like elegant codes in C++, as if we are using Unity! -
Even stronger than C#.
The ARIA property system is even stronger than the C# built-in features. You can write properties with arbitrary number and type of parameters. For example, suppose you are writing a 2D fluid simulator based on the lattice Boltzmann method (LBM), your code may look like this:
using I0 = std::integral_constant<int, 0>; using I1 = std::integral_constant<int, 1>; using I2 = std::integral_constant<int, 2>; ... // The streaming process of the LBM. grid.f(coord, I0{}) = grid.fPost(coord - Coord{0, 0}, I0{}); grid.f(coord, I1{}) = grid.fPost(coord - Coord{1, 0}, I1{}); grid.f(coord, I2{}) = grid.fPost(coord - Coord{0, 1}, I2{}); ...
Here, both properties,
fandfPost, have 2 parameters, where the first type isCoord(means coordinate), and the second type can be anystd::integral_constant(means the LBM velocity set).Only several lines of codes are needed to generate such complex properties.
-
Make
autosafe in ARIA.To make
autosafe, ARIA usesauto + Auto()type deduction:Vec3r a = {1, 2, 3}; Vec3r b = {2, 4, 6}; // NO. auto c = a.cross(b); // YES. Vec3r c0 = a.cross(b); auto c1 = Auto(a.cross(b)); // With `auto + Auto()` type deduction, type of `c1` is correctly deduced to `Vec3r`.Auto()helps better deduce the types from all proxy systems used in ARIA, which makes our codes safe. Read the comments inAuto.handProperty.hto see how to use them. -
Make life easier for small projects.
Suppose you are writing a very small project based on ARIA, it is very annoying to use
auto + Autotype deduction everywhere. Instead, we want to useAutoonly when we have to, which means that the compiler should be able to tell us:- Which
autois unsafe and refuse to compile them, - Which
Autois unnecessary and refuse to compile them.
So,
let + Lettype deduction is introduced to make life easier for small projects:let x = 10; let x = Let(10); // Compile error. std::vector<bool> v(1); let y = v[0]; // Compile error. let y = Let(v[0]);
Read the comments in
Let.hto see how to use them, and feel free to uselet + Letinstead ofauto + Auto. - Which
-
Coding standards.
ARIA uses the coding standards similar to https://llvm.org/docs/CodingStandards.html but very different in naming. Please exactly follow the style of
ARIA::Core. Read the codes and you will understand.