diff --git a/CodeGen/VectorGen/.gitignore b/CodeGen/VectorGen/.gitignore index 5f0e724..5b7e8f0 100644 --- a/CodeGen/VectorGen/.gitignore +++ b/CodeGen/VectorGen/.gitignore @@ -1,2 +1,3 @@ # Result -*.hpp +VxTypes.hpp +VxTypes.cpp diff --git a/CodeGen/VectorGen/VxTypes.backups.hpp b/CodeGen/VectorGen/VxTypes.backups.hpp new file mode 100644 index 0000000..e3b9a56 --- /dev/null +++ b/CodeGen/VectorGen/VxTypes.backups.hpp @@ -0,0 +1,347 @@ + +struct VxVector2 { + CKFLOAT x, y; + VxVector2() : x(0.0f), y(0.0f) {} + VxVector2(CKFLOAT _x, CKFLOAT _y) : x(_x), y(_y) {} + YYCC_DEF_CLS_COPY_MOVE(VxVector2); + CKFLOAT& operator[](size_t i) { + switch (i) { + case 0: return x; + case 1: return y; + default: throw LogicException("Invalid index for VxVector2::operator[]."); + } + } + const CKFLOAT& operator[](size_t i) const { + switch (i) { + case 0: return x; + case 1: return y; + default: throw LogicException("Invalid index for VxVector2::operator[]."); + } + } + VxVector2& operator+=(const VxVector2& rhs) { + x += rhs.x; + y += rhs.y; + return *this; + } + friend VxVector2 operator+(const VxVector2& lhs, const VxVector2& rhs) { + return VxVector2(lhs.x + rhs.x, lhs.y + rhs.y); + } + VxVector2& operator-=(const VxVector2& rhs) { + x -= rhs.x; + y -= rhs.y; + return *this; + } + friend VxVector2 operator-(const VxVector2& lhs, const VxVector2& rhs) { + return VxVector2(lhs.x - rhs.x, lhs.y - rhs.y); + } + VxVector2& operator*=(CKFLOAT rhs) { + x *= rhs; + y *= rhs; + return *this; + } + friend VxVector2 operator*(const VxVector2& lhs, CKFLOAT rhs) { + return VxVector2(lhs.x * rhs, lhs.y * rhs); + } + friend VxVector2 operator*(CKFLOAT lhs, const VxVector2& rhs) { + return VxVector2(lhs * rhs.x, lhs * rhs.y); + } + friend CKFLOAT operator*(const VxVector2& lhs, const VxVector2& rhs) { + return (lhs.x * rhs.x + lhs.y * rhs.y); + } + VxVector2& operator/=(CKFLOAT rhs) { + if (rhs == 0.0f) return *this; + x /= rhs; + y /= rhs; + return *this; + } + friend VxVector2 operator/(const VxVector2& lhs, CKFLOAT rhs) { + if (rhs == 0.0f) return VxVector2(0.0f, 0.0f); + return VxVector2(lhs.x / rhs, lhs.y / rhs); + } + bool operator==(const VxVector2& rhs) const { + return (x == rhs.x && y == rhs.y); + } + auto operator<=>(const VxVector2& rhs) const { + if (auto cmp = x <=> rhs.x; cmp != 0) return cmp; + return y <=> rhs.y; + } + CKFLOAT SquaredLength() const { + return (x * x + y * y); + } + CKFLOAT Length() const { + return std::sqrt(SquaredLength()); + } + void Normalized() { + CKFLOAT len = Length(); + if (len == 0.0f) return; + x /= len; + y /= len; + } + VxVector2 Normalize() const { + CKFLOAT len = Length(); + if (len == 0.0f) return VxVector2(); + return VxVector2(x / len, y / len); + } +}; + +struct VxVector3 { + CKFLOAT x, y, z; + VxVector3() : x(0.0f), y(0.0f), z(0.0f) {} + VxVector3(CKFLOAT _x, CKFLOAT _y, CKFLOAT _z) : x(_x), y(_y), z(_z) {} + YYCC_DEF_CLS_COPY_MOVE(VxVector3); + CKFLOAT& operator[](size_t i) { + switch (i) { + case 0: return x; + case 1: return y; + case 2: return z; + default: throw LogicException("Invalid index for VxVector3::operator[]."); + } + } + const CKFLOAT& operator[](size_t i) const { + switch (i) { + case 0: return x; + case 1: return y; + case 2: return z; + default: throw LogicException("Invalid index for VxVector3::operator[]."); + } + } + VxVector3& operator+=(const VxVector3& rhs) { + x += rhs.x; + y += rhs.y; + z += rhs.z; + return *this; + } + friend VxVector3 operator+(const VxVector3& lhs, const VxVector3& rhs) { + return VxVector3(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z); + } + VxVector3& operator-=(const VxVector3& rhs) { + x -= rhs.x; + y -= rhs.y; + z -= rhs.z; + return *this; + } + friend VxVector3 operator-(const VxVector3& lhs, const VxVector3& rhs) { + return VxVector3(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z); + } + VxVector3& operator*=(CKFLOAT rhs) { + x *= rhs; + y *= rhs; + z *= rhs; + return *this; + } + friend VxVector3 operator*(const VxVector3& lhs, CKFLOAT rhs) { + return VxVector3(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs); + } + friend VxVector3 operator*(CKFLOAT lhs, const VxVector3& rhs) { + return VxVector3(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z); + } + friend CKFLOAT operator*(const VxVector3& lhs, const VxVector3& rhs) { + return (lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z); + } + VxVector3& operator/=(CKFLOAT rhs) { + if (rhs == 0.0f) return *this; + x /= rhs; + y /= rhs; + z /= rhs; + return *this; + } + friend VxVector3 operator/(const VxVector3& lhs, CKFLOAT rhs) { + if (rhs == 0.0f) return VxVector3(0.0f, 0.0f, 0.0f); + return VxVector3(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs); + } + bool operator==(const VxVector3& rhs) const { + return (x == rhs.x && y == rhs.y && z == rhs.z); + } + auto operator<=>(const VxVector3& rhs) const { + if (auto cmp = x <=> rhs.x; cmp != 0) return cmp; + if (auto cmp = y <=> rhs.y; cmp != 0) return cmp; + return z <=> rhs.z; + } + CKFLOAT SquaredLength() const { + return (x * x + y * y + z * z); + } + CKFLOAT Length() const { + return std::sqrt(SquaredLength()); + } + void Normalized() { + CKFLOAT len = Length(); + if (len == 0.0f) return; + x /= len; + y /= len; + z /= len; + } + VxVector3 Normalize() const { + CKFLOAT len = Length(); + if (len == 0.0f) return VxVector3(); + return VxVector3(x / len, y / len, z / len); + } +}; + +struct VxVector4 { + CKFLOAT x, y, z, w; + VxVector4() : x(0.0f), y(0.0f), z(0.0f), w(0.0f) {} + VxVector4(CKFLOAT _x, CKFLOAT _y, CKFLOAT _z, CKFLOAT _w) : x(_x), y(_y), z(_z), w(_w) {} + YYCC_DEF_CLS_COPY_MOVE(VxVector4); + CKFLOAT& operator[](size_t i) { + switch (i) { + case 0: return x; + case 1: return y; + case 2: return z; + case 3: return w; + default: throw LogicException("Invalid index for VxVector4::operator[]."); + } + } + const CKFLOAT& operator[](size_t i) const { + switch (i) { + case 0: return x; + case 1: return y; + case 2: return z; + case 3: return w; + default: throw LogicException("Invalid index for VxVector4::operator[]."); + } + } + VxVector4& operator+=(const VxVector4& rhs) { + x += rhs.x; + y += rhs.y; + z += rhs.z; + w += rhs.w; + return *this; + } + friend VxVector4 operator+(const VxVector4& lhs, const VxVector4& rhs) { + return VxVector4(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w); + } + VxVector4& operator-=(const VxVector4& rhs) { + x -= rhs.x; + y -= rhs.y; + z -= rhs.z; + w -= rhs.w; + return *this; + } + friend VxVector4 operator-(const VxVector4& lhs, const VxVector4& rhs) { + return VxVector4(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w); + } + VxVector4& operator*=(CKFLOAT rhs) { + x *= rhs; + y *= rhs; + z *= rhs; + w *= rhs; + return *this; + } + friend VxVector4 operator*(const VxVector4& lhs, CKFLOAT rhs) { + return VxVector4(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs, lhs.w * rhs); + } + friend VxVector4 operator*(CKFLOAT lhs, const VxVector4& rhs) { + return VxVector4(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z, lhs * rhs.w); + } + friend CKFLOAT operator*(const VxVector4& lhs, const VxVector4& rhs) { + return (lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z + lhs.w * rhs.w); + } + VxVector4& operator/=(CKFLOAT rhs) { + if (rhs == 0.0f) return *this; + x /= rhs; + y /= rhs; + z /= rhs; + w /= rhs; + return *this; + } + friend VxVector4 operator/(const VxVector4& lhs, CKFLOAT rhs) { + if (rhs == 0.0f) return VxVector4(0.0f, 0.0f, 0.0f, 0.0f); + return VxVector4(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs, lhs.w / rhs); + } + bool operator==(const VxVector4& rhs) const { + return (x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w); + } + auto operator<=>(const VxVector4& rhs) const { + if (auto cmp = x <=> rhs.x; cmp != 0) return cmp; + if (auto cmp = y <=> rhs.y; cmp != 0) return cmp; + if (auto cmp = z <=> rhs.z; cmp != 0) return cmp; + return w <=> rhs.w; + } + CKFLOAT SquaredLength() const { + return (x * x + y * y + z * z + w * w); + } + CKFLOAT Length() const { + return std::sqrt(SquaredLength()); + } + void Normalized() { + CKFLOAT len = Length(); + if (len == 0.0f) return; + x /= len; + y /= len; + z /= len; + w /= len; + } + VxVector4 Normalize() const { + CKFLOAT len = Length(); + if (len == 0.0f) return VxVector4(); + return VxVector4(x / len, y / len, z / len, w / len); + } +}; + +struct VxQuaternion { + CKFLOAT x, y, z, w; + VxQuaternion() : x(0.0f), y(0.0f), z(0.0f), w(0.0f) {} // set your custom init. + VxQuaternion(CKFLOAT _x, CKFLOAT _y, CKFLOAT _z, CKFLOAT _w) : x(_x), y(_y), z(_z), w(_w) {} + YYCC_DEF_CLS_COPY_MOVE(VxQuaternion); + CKFLOAT& operator[](size_t i) { + switch (i) { + case 0: return x; + case 1: return y; + case 2: return z; + case 3: return w; + default: throw LogicException("Invalid index for VxQuaternion::operator[]."); + } + } + const CKFLOAT& operator[](size_t i) const { + switch (i) { + case 0: return x; + case 1: return y; + case 2: return z; + case 3: return w; + default: throw LogicException("Invalid index for VxQuaternion::operator[]."); + } + } + bool operator==(const VxQuaternion& rhs) const { + return (x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w); + } + auto operator<=>(const VxQuaternion& rhs) const { + if (auto cmp = x <=> rhs.x; cmp != 0) return cmp; + if (auto cmp = y <=> rhs.y; cmp != 0) return cmp; + if (auto cmp = z <=> rhs.z; cmp != 0) return cmp; + return w <=> rhs.w; + } +}; + +struct VxColor { + CKFLOAT r, g, b, a; + VxColor() : r(0.0f), g(0.0f), b(0.0f), a(0.0f) {} // set your custom init. + VxColor(CKFLOAT _r, CKFLOAT _g, CKFLOAT _b, CKFLOAT _a) : r(_r), g(_g), b(_b), a(_a) {} + YYCC_DEF_CLS_COPY_MOVE(VxColor); + CKFLOAT& operator[](size_t i) { + switch (i) { + case 0: return r; + case 1: return g; + case 2: return b; + case 3: return a; + default: throw LogicException("Invalid index for VxColor::operator[]."); + } + } + const CKFLOAT& operator[](size_t i) const { + switch (i) { + case 0: return r; + case 1: return g; + case 2: return b; + case 3: return a; + default: throw LogicException("Invalid index for VxColor::operator[]."); + } + } + bool operator==(const VxColor& rhs) const { + return (r == rhs.r && g == rhs.g && b == rhs.b && a == rhs.a); + } + auto operator<=>(const VxColor& rhs) const { + if (auto cmp = r <=> rhs.r; cmp != 0) return cmp; + if (auto cmp = g <=> rhs.g; cmp != 0) return cmp; + if (auto cmp = b <=> rhs.b; cmp != 0) return cmp; + return a <=> rhs.a; + } +}; diff --git a/CodeGen/VectorGen/VxTypes.cpp.jinja b/CodeGen/VectorGen/VxTypes.cpp.jinja new file mode 100644 index 0000000..daad2e3 --- /dev/null +++ b/CodeGen/VectorGen/VxTypes.cpp.jinja @@ -0,0 +1,178 @@ +{% import 'VxTypes.shared.jinja' as shared %} +{# +For friend operator overload, we do not need add CLASSNAME:: prefix for it. +Because they are not a part of that class. +#} + +#pragma region {{ sname }} + +{#- Ctor type 1 - Default ctor #} +{{ sname }}::{{ sname }}() : {{- shared.initialize_list_builder(svars, False) -}} {} +{#- Ctor type 2 - User specified ctor #} +{{ sname }}::{{ sname }}({{- shared.argument_list_builder(svars) -}}) : {{- shared.initialize_list_builder(svars, True) -}} {} + +{#- Offset operator #} +CKFLOAT& {{ sname }}::operator[](size_t i) { + switch (i) { + {%- for item in svars %} + case {{ loop.index0 }}: return item; + {%- endfor %} + default: throw LogicException("Invalid index for {{ sname }}::operator[]."); + } +} +const CKFLOAT& {{ sname }}::operator[](size_t i) const { + switch (i) { + {%- for item in svars %} + case {{ loop.index0 }}: return {{ item }}; + {%- endfor %} + default: throw LogicException("Invalid index for {{ sname }}::operator[]."); + } +} + +{#- Equal operator #} +bool {{ sname }}::operator==(const {{ sname }}& rhs) const { + return ( + {%- for item in svars %} + lhs.{{ item }} * rhs.{{ item }} {% if not loop.last %} && {% endif %} + {%- endfor %} + ); +} + +{#- Spaceship operator #} +auto {{ sname }}::operator<=>(const {{ sname }}& rhs) const { + {%- for item in svars[:-1] %} + if (auto cmp = {{ item }} <=> rhs.{{ item }}; cmp != 0) return cmp; + {%- endfor %} + return svars[-1] <=> rhs.svars[-1]; +} + + +{#- BEGIN VECTOR SPECIFIC #} +{%- if is_vector %} + +{#- Add, minus operators #} +{#- Unary operators #} +{{ sname }} {{ sname }}::operator+() const { + return *this; +} +{{ sname }} {{ sname }}::operator-() const { + return {{ sname }}( + {%- for item in svars %} + -{{ item }} {%- if not loop.last %}, {% endif %} + {%- endfor %} + ); +} +{#- Additive operators #} +{{ sname }}& {{ sname }}::operator+=(const {{ sname }}& rhs) { + {%- for item in svars %} + {{ item }} += rhs.{{ item }}; + {%- endfor %} + return *this; +} +{{ sname }} operator+(const {{ sname }}& lhs, const {{ sname }}& rhs) { + return {{ sname }}( + {%- for item in svars %} + lhs.{{ item }} + rhs.{{ item }} {%- if not loop.last %}, {% endif %} + {%- endfor %} + ); +} +{{ sname }}& {{ sname }}::operator-=(const {{ sname }}& rhs) { + {%- for item in svars %} + {{ item }} -= rhs.{{ item }}; + {%- endfor %} + return *this; +} +{{ sname }} operator-(const {{ sname }}& lhs, const {{ sname }}& rhs) { + return {{ sname }}( + {%- for item in svars %} + lhs.{{ item }} - rhs.{{ item }} {%- if not loop.last %}, {% endif %} + {%- endfor %} + ); +} + +{#- Mul operator #} +{{ sname }}& {{ sname }}::operator*=(CKFLOAT rhs) { + {%- for item in svars %} + {{ item }} *= rhs; + {%- endfor %} + return *this; +} +{{ sname }} operator*(const {{ sname }}& lhs, CKFLOAT rhs) { + return {{ sname }}( + {%- for item in svars %} + lhs.{{ item }} * rhs {%- if not loop.last %}, {% endif %} + {%- endfor %} + ); +} +{{ sname }} operator*(CKFLOAT lhs, const {{ sname }}& rhs) { + return {{ sname }}( + {%- for item in svars %} + lhs.{{ item }} * rhs {%- if not loop.last %}, {% endif %} + {%- endfor %} + ); +} +CKFLOAT operator*(const {{ sname }}& lhs, const {{ sname }}& rhs) { + return ( + {%- for item in svars %} + lhs.{{ item }} * rhs.{{ item }} {%- if not loop.last %} + {% endif %} + {%- endfor %} + ); +} + +{#- Div operator #} +{{ sname }}& {{ sname }}::operator/=(CKFLOAT rhs) { + if (rhs == 0.0f) return *this; + {%- for item in svars %} + {{ item }} /= rhs; + {%- endfor %} + return *this; +} +{{ sname }} operator/(const {{ sname }}& lhs, CKFLOAT rhs) { + if (rhs == 0.0f) return {{ sname }}(0.0f, 0.0f); + return {{ sname }}( + {%- for item in svars %} + lhs.{{ item }} / rhs {%- if not loop.last %}, {% endif %} + {%- endfor %} + ); +} + +{#- Length functions #} +CKFLOAT {{ sname }}::SquaredLength() const { + return ( + {%- for item in svars %} + {{ item }} * {{ item }} {%- if not loop.last %} + {% endif %} + {%- endfor %} + ); +} +CKFLOAT {{ sname }}::Length() const { + return std::sqrt(SquaredLength()); +} + +{#- Normalize functions #} +void {{ sname }}::Normalized() { + CKFLOAT len = Length(); + if (len == 0.0f) return; + {%- for item in svars %} + {{ item }} /= len; + {%- endfor %} +} +{{ sname }} {{ sname }}::Normalize() const { + CKFLOAT len = Length(); + if (len == 0.0f) return {{ sname }}(); + return {{ sname }}( + {%- for item in svars %} + {{ item }} / len {%- if not loop.last %} + {% endif %} + {%- endfor %} + ); +} + +{%- endif %} +{#- END VECTOR SPECIFIC #} + + +{#- User custom region #} + +/* ===== BEGIN USER CUSTOM ===== */ +/* ===== END USER CUSTOM ===== */ + +#pragma endregion diff --git a/CodeGen/VectorGen/VxTypes.hpp.jinja b/CodeGen/VectorGen/VxTypes.hpp.jinja new file mode 100644 index 0000000..f3a7631 --- /dev/null +++ b/CodeGen/VectorGen/VxTypes.hpp.jinja @@ -0,0 +1,65 @@ +{% import 'VxTypes.shared.jinja' as shared %} + +struct {{ sname }} { + {#- Variable declaration #} + CKFLOAT {{ ", ".join(svars) }}; + + {#- Ctor type 1 - Default ctor #} + {{ sname }}(); + {#- Ctor type 2 - User specified ctor #} + {{ sname }}({{- shared.argument_list_builder(svars) -}}); + + {#- Default copy ctor, move ctor, copy assigner, move assigner #} + YYCC_DEF_CLS_COPY_MOVE({{ sname }}); + + {#- Offset operator #} + CKFLOAT& operator[](size_t i); + const CKFLOAT& operator[](size_t i) const; + + {#- Equal operator #} + bool operator==(const {{ sname }}& rhs) const; + + {#- Spaceship operator #} + auto operator<=>(const {{ sname }}& rhs) const; + + + {#- BEGIN VECTOR SPECIFIC #} + {%- if is_vector %} + + {#- Add, minus operators #} + {#- Unary operators #} + {{ sname }} operator+() const; + {{ sname }} operator-() const; + {#- Additive operators #} + {{ sname }}& operator+=(const {{ sname }}& rhs); + friend {{ sname }} operator+(const {{ sname }}& lhs, const {{ sname }}& rhs); + {{ sname }}& operator-=(const {{ sname }}& rhs); + friend {{ sname }} operator-(const {{ sname }}& lhs, const {{ sname }}& rhs); + + {#- Mul operator #} + {{ sname }}& operator*=(CKFLOAT rhs); + friend {{ sname }} operator*(const {{ sname }}& lhs, CKFLOAT rhs); + friend {{ sname }} operator*(CKFLOAT lhs, const {{ sname }}& rhs); + friend CKFLOAT operator*(const {{ sname }}& lhs, const {{ sname }}& rhs); + + {#- Div operator #} + {{ sname }}& operator/=(CKFLOAT rhs); + friend {{ sname }} operator/(const {{ sname }}& lhs, CKFLOAT rhs); + + {#- Length functions #} + CKFLOAT SquaredLength() const; + CKFLOAT Length() const; + + {#- Normalize functions #} + void Normalized(); + {{ sname }} Normalize() const; + + {%- endif %} + {#- END VECTOR SPECIFIC #} + + + {#- User custom region #} + + /* ===== BEGIN USER CUSTOM ===== */ + /* ===== END USER CUSTOM ===== */ +}; diff --git a/CodeGen/VectorGen/VxTypes.shared.jinja b/CodeGen/VectorGen/VxTypes.shared.jinja new file mode 100644 index 0000000..555a9aa --- /dev/null +++ b/CodeGen/VectorGen/VxTypes.shared.jinja @@ -0,0 +1,21 @@ +{# +The macro to generate C++ ctor argument list +It produce like this: `CKFLOAT _x, CKFLOAT _y, CKFLOAT _z, CKFLOAT _w` +#} +{% macro argument_list_builder(svars) %} +{%- for item in svars -%} +CKFLOAT _{{- item -}}{%- if not loop.last %}, {% endif -%} +{%- endfor -%} +{% endmacro %} + +{# +The macro to generate C++ ctor initialize list +It produce like this: `x(0.0f), y(0.0f), z(0.0f), w(0.0f)` +or this: `x(_x), y(_y), z(_z), w(_w)` +according to user request. +#} +{% macro initialize_list_builder(svars, is_user) %} +{%- for item in svars -%} +{{- item -}}({%- if is_user -%}_{{- item -}}{%- else -%}0.0f{%- endif -%}){%- if not loop.last %}, {% endif -%} +{%- endfor -%} +{% endmacro %} diff --git a/CodeGen/VectorGen/VxVectors.py b/CodeGen/VectorGen/VxVectorGen.old.py similarity index 100% rename from CodeGen/VectorGen/VxVectors.py rename to CodeGen/VectorGen/VxVectorGen.old.py diff --git a/CodeGen/VectorGen/VxVectorGen.py b/CodeGen/VectorGen/VxVectorGen.py new file mode 100644 index 0000000..3c2abc7 --- /dev/null +++ b/CodeGen/VectorGen/VxVectorGen.py @@ -0,0 +1,63 @@ +import os +import io +import typing +import jinja2 + +g_HppTemplateFile: str = 'VxTypes.hpp.jinja' +g_CppTemplateFile: str = 'VxTypes.cpp.jinja' + +g_ResultHppFile: str = 'VxTypes.hpp' +g_ResultCppFile: str = 'VxTypes.cpp' + +def get_root_directory() -> str: + return os.path.dirname(__file__) + +class TemplateRender: + m_Loader: jinja2.BaseLoader + m_Environment: jinja2.Environment + + m_HppTemplate: jinja2.Template + m_CppTemplate: jinja2.Template + + m_OutputHpp: io.TextIOWrapper + m_OutputCpp: io.TextIOWrapper + + def __init__(self, output_hpp_path: str, output_cpp_path: str) -> None: + self.m_Loader = jinja2.FileSystemLoader(get_root_directory()) + self.m_Environment = jinja2.Environment(loader=self.m_Loader) + + self.m_HppTemplate = self.m_Environment.get_template(g_HppTemplateFile) + self.m_CppTemplate = self.m_Environment.get_template(g_CppTemplateFile) + + self.m_OutputHpp = open(os.path.join(get_root_directory(), output_hpp_path), 'w', encoding='utf-8') + self.m_OutputCpp = open(os.path.join(get_root_directory(), output_cpp_path), 'w', encoding='utf-8') + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, traceback): + self.m_OutputHpp.close() + self.m_OutputCpp.close() + + def __render(self, sname: str, is_vector: bool, svars: tuple[str]) -> None: + template_argument: dict[str, typing.Any] = { + 'sname': sname, + 'is_vector': is_vector, + 'svars': svars + } + self.m_OutputHpp.write(self.m_HppTemplate.render(**template_argument)) + self.m_OutputCpp.write(self.m_CppTemplate.render(**template_argument)) + + def render_vector(self, sname: str, svars: tuple[str]) -> None: + self.__render(sname, True, svars) + + def render_others(self, sname: str, svars: tuple[str]) -> None: + self.__render(sname, False, svars) + +if __name__ == '__main__': + with TemplateRender(g_ResultHppFile, g_ResultCppFile) as render: + render.render_vector('VxVector2', ('x', 'y', )) + render.render_vector('VxVector3', ('x', 'y', 'z', )) + render.render_vector('VxVector4', ('x', 'y', 'z', 'w', )) + render.render_others('VxQuaternion', ('x', 'y', 'z', 'w', )) + render.render_others('VxColor', ('r', 'g', 'b', 'a', )) diff --git a/LibCmo/CK2/ObjImpls/CKCamera.cpp b/LibCmo/CK2/ObjImpls/CKCamera.cpp index 02bb0cd..c5d2272 100644 --- a/LibCmo/CK2/ObjImpls/CKCamera.cpp +++ b/LibCmo/CK2/ObjImpls/CKCamera.cpp @@ -3,4 +3,45 @@ namespace LibCmo::CK2::ObjImpls { +#pragma region Class Operations + + CK_CAMERA_PROJECTION CKCamera::GetProjectionType() const { + return CK_CAMERA_PROJECTION(); + } + void CKCamera::SetProjectionType(CK_CAMERA_PROJECTION proj) {} + + CKFLOAT CKCamera::GetOrthographicZoom() const { + return CKFLOAT(); + } + void CKCamera::SetOrthographicZoom(CKFLOAT zoom) {} + + CKFLOAT CKCamera::GetFrontPlane() const { + return CKFLOAT(); + } + CKFLOAT CKCamera::GetBackPlane() const { + return CKFLOAT(); + } + CKFLOAT CKCamera::GetFov() const { + return CKFLOAT(); + } + void CKCamera::SetFrontPlane(CKFLOAT front) {} + void CKCamera::SetBackPlane(CKFLOAT back) {} + void CKCamera::SetFov(CKFLOAT fov) {} + + void CKCamera::GetAspectRatio(int& width, int& height) const {} + void CKCamera::SetAspectRatio(int width, int height) {} + + void CKCamera::ComputeProjectionMatrix(VxMath::VxMatrix& mat) const {} + + void CKCamera::ResetRoll() {} + void CKCamera::Roll(CKFLOAT angle) {} + + CK3dEntity* CKCamera::GetTarget() const { + return nullptr; + } + void CKCamera::SetTarget(CK3dEntity* target) {} + +#pragma endregion + + } diff --git a/LibCmo/CK2/ObjImpls/CKLight.cpp b/LibCmo/CK2/ObjImpls/CKLight.cpp index 5054138..7dd3e83 100644 --- a/LibCmo/CK2/ObjImpls/CKLight.cpp +++ b/LibCmo/CK2/ObjImpls/CKLight.cpp @@ -131,7 +131,6 @@ namespace LibCmo::CK2::ObjImpls { VxMath::VXLIGHT_TYPE CKLight::GetType() const { return m_LightData.m_Type; } - void CKLight::SetType(VxMath::VXLIGHT_TYPE light_type) { m_LightData.m_Type = light_type; } @@ -139,7 +138,6 @@ namespace LibCmo::CK2::ObjImpls { const VxMath::VxColor& CKLight::GetColor() const { return m_LightData.m_Diffuse; } - void CKLight::SetColor(const VxMath::VxColor& c) { m_LightData.m_Diffuse = c; } @@ -147,23 +145,18 @@ namespace LibCmo::CK2::ObjImpls { CKFLOAT CKLight::GetConstantAttenuation() const { return m_LightData.m_Attenuation0; } - CKFLOAT CKLight::GetLinearAttenuation() const { return m_LightData.m_Attenuation1; } - CKFLOAT CKLight::GetQuadraticAttenuation() const { return m_LightData.m_Attenuation2; } - void CKLight::SetConstantAttenuation(CKFLOAT value) { m_LightData.m_Attenuation0 = value; } - void CKLight::SetLinearAttenuation(CKFLOAT value) { m_LightData.m_Attenuation1 = value; } - void CKLight::SetQuadraticAttenuation(CKFLOAT value) { m_LightData.m_Attenuation2 = value; } @@ -171,7 +164,6 @@ namespace LibCmo::CK2::ObjImpls { CKFLOAT CKLight::GetRange() const { return m_LightData.m_Range; } - void CKLight::SetRange(CKFLOAT value) { m_LightData.m_Range = value; } @@ -179,23 +171,18 @@ namespace LibCmo::CK2::ObjImpls { CKFLOAT CKLight::GetHotSpot() const { return m_LightData.m_InnerSpotCone; } - CKFLOAT CKLight::GetFalloff() const { return m_LightData.m_OuterSpotCone; } - CKFLOAT CKLight::GetFalloffShape() const { return m_LightData.m_Falloff; } - void CKLight::SetHotSpot(CKFLOAT value) { m_LightData.m_InnerSpotCone = value; } - void CKLight::SetFalloff(CKFLOAT value) { m_LightData.m_OuterSpotCone = value; } - void CKLight::SetFalloffShape(CKFLOAT value) { m_LightData.m_Falloff = value; } @@ -203,7 +190,6 @@ namespace LibCmo::CK2::ObjImpls { bool CKLight::GetActivity() const { return YYCC::EnumHelper::Has(m_LightFlags, LightFlags::Active); } - void CKLight::Active(bool active) { if (active) { YYCC::EnumHelper::Add(m_LightFlags, LightFlags::Active); @@ -215,7 +201,6 @@ namespace LibCmo::CK2::ObjImpls { bool CKLight::GetSpecularFlag() const { return YYCC::EnumHelper::Has(m_LightFlags, LightFlags::Specular); } - void CKLight::SetSpecularFlag(bool specular) { if (specular) { YYCC::EnumHelper::Add(m_LightFlags, LightFlags::Specular); @@ -229,7 +214,6 @@ namespace LibCmo::CK2::ObjImpls { // So it always return nullptr. return nullptr; } - void CKLight::SetTarget(CK3dEntity* target) { // Normal light do not support target. // So, do nothing. @@ -238,7 +222,6 @@ namespace LibCmo::CK2::ObjImpls { CKFLOAT CKLight::GetLightPower() const { return m_LightPower; } - void CKLight::SetLightPower(CKFLOAT power) { m_LightPower = power; } diff --git a/LibCmo/CMakeLists.txt b/LibCmo/CMakeLists.txt index 9d32080..7a65020 100644 --- a/LibCmo/CMakeLists.txt +++ b/LibCmo/CMakeLists.txt @@ -36,6 +36,7 @@ PRIVATE CK2/ObjImpls/CKTargetCamera.cpp # VxMath VxMath/VxMemoryMappedFile.cpp + VxMath/VxTypes.cpp VxMath/VxMath.cpp # X Container XContainer/XTypes.cpp diff --git a/LibCmo/VxMath/VxMath.cpp b/LibCmo/VxMath/VxMath.cpp index c822e80..00f71b2 100644 --- a/LibCmo/VxMath/VxMath.cpp +++ b/LibCmo/VxMath/VxMath.cpp @@ -134,39 +134,4 @@ namespace LibCmo::VxMath { #pragma endregion -#pragma region Patched - - namespace NSVxVector { - - float DotProduct(const VxVector2& lhs, const VxVector2& rhs) { - return lhs * rhs; - } - - float DotProduct(const VxVector3& lhs, const VxVector3& rhs) { - return lhs * rhs; - } - - float DotProduct(const VxVector4& lhs, const VxVector4& rhs) { - return lhs * rhs; - } - - VxVector3 CrossProduct(const VxVector3& lhs, const VxVector3& rhs) { - return VxVector3( - lhs.y * rhs.z - lhs.z * rhs.y, - lhs.z * rhs.x - lhs.x * rhs.z, - lhs.x * rhs.y - lhs.y * rhs.x - ); - } - - void Abs(VxVector3& lhs) { - lhs.x = std::fabs(lhs.x); - lhs.y = std::fabs(lhs.y); - lhs.z = std::fabs(lhs.z); - } - - } - -#pragma endregion - - } diff --git a/LibCmo/VxMath/VxMath.hpp b/LibCmo/VxMath/VxMath.hpp index 5a3de26..75d90cb 100644 --- a/LibCmo/VxMath/VxMath.hpp +++ b/LibCmo/VxMath/VxMath.hpp @@ -95,56 +95,5 @@ namespace LibCmo::VxMath { */ void VxDoAlphaBlit(VxImageDescEx* dst_desc, const CKBYTE* AlphaValues); - - // ========== Patch Section ========== - - /** - * @brief The patch namespace for VxVector-like classes - * @details This namespace provides VxVector-like classes member functions which presented in original Virtools SDK. - * These functions are put in public namespace in original Virtools SDK. - * We just organise them into an unique namespace. - */ - namespace NSVxVector { - - /** - * @brief Dot product 2 2d vectors. - * @param[in] lhs The left side vector of dot product symbol. - * @param[in] rhs The right side vector of dot product symbol. - * @return The float pointing result of dot product. - */ - CKFLOAT DotProduct(const VxVector2& lhs, const VxVector2& rhs); - /** - * @brief Dot product 2 3d vectors. - * @param[in] lhs The left side vector of dot product symbol. - * @param[in] rhs The right side vector of dot product symbol. - * @return The float pointing result of dot product. - */ - CKFLOAT DotProduct(const VxVector3& lhs, const VxVector3& rhs); - /** - * @brief Dot product 2 4d vectors. - * @param[in] lhs The left side vector of dot product symbol. - * @param[in] rhs The right side vector of dot product symbol. - * @return The float pointing result of dot product. - */ - CKFLOAT DotProduct(const VxVector4& lhs, const VxVector4& rhs); - - /** - * @brief Cross product 2 3d vectors. - * @param[in] lhs The left side vector of cross product symbol. - * @param[in] rhs The right side vector of cross product symbol. - * @return The 3d vector result of cross product. - */ - VxVector3 CrossProduct(const VxVector3& lhs, const VxVector3& rhs); - - /** - * @brief Set all factor in vector to its absolute value. - * @param[in,out] lhs The vector for processing. - * @remarks This function is rarely used. - * Please note this function is not calculate the absolute value of vector. - */ - void Abs(VxVector3& lhs); - - } - } diff --git a/LibCmo/VxMath/VxTypes.cpp b/LibCmo/VxMath/VxTypes.cpp new file mode 100644 index 0000000..e81ad4f --- /dev/null +++ b/LibCmo/VxMath/VxTypes.cpp @@ -0,0 +1,59 @@ +#include "VxTypes.hpp" + +namespace LibCmo::VxMath { + +#pragma region Patched + + namespace NSVxVector { + + float DotProduct(const VxVector2& lhs, const VxVector2& rhs) { + return lhs * rhs; + } + + float DotProduct(const VxVector3& lhs, const VxVector3& rhs) { + return lhs * rhs; + } + + float DotProduct(const VxVector4& lhs, const VxVector4& rhs) { + return lhs * rhs; + } + + VxVector3 CrossProduct(const VxVector3& lhs, const VxVector3& rhs) { + return VxVector3( + lhs.y * rhs.z - lhs.z * rhs.y, + lhs.z * rhs.x - lhs.x * rhs.z, + lhs.x * rhs.y - lhs.y * rhs.x + ); + } + + void Abs(VxVector3& lhs) { + lhs.x = std::fabs(lhs.x); + lhs.y = std::fabs(lhs.y); + lhs.z = std::fabs(lhs.z); + } + + } + + namespace NSVxMatrix { + + void Perspective(VxMatrix& mat, float Fov, float Aspect, float Near_plane, float Far_plane) { + + } + + void PerspectiveRect(VxMatrix& mat, float Left, float Right, float Top, float Bottom, float Near_plane, float Far_plane) { + + } + + void Orthographic(VxMatrix& mat, float Zoom, float Aspect, float Near_plane, float Far_plane) { + + } + + void OrthographicRect(VxMatrix& mat, float Left, float Right, float Top, float Bottom, float Near_plane, float Far_plane) { + + } + + } + +#pragma endregion + +} diff --git a/LibCmo/VxMath/VxTypes.hpp b/LibCmo/VxMath/VxTypes.hpp index 7eade8f..f758eab 100644 --- a/LibCmo/VxMath/VxTypes.hpp +++ b/LibCmo/VxMath/VxTypes.hpp @@ -23,7 +23,7 @@ namespace LibCmo::VxMath { class VxMemoryMappedFile; - // Misc + // ========== Vector-like Definition ========== /** * @brief The representation of a Vector in 2 dimensions. @@ -403,6 +403,7 @@ namespace LibCmo::VxMath { return a <=> rhs.a; } + // ===== BEGIN USER CUSTOM ===== VxColor(CKFLOAT _r, CKFLOAT _g, CKFLOAT _b) : r(_r), g(_g), b(_b), a(1.0f) {} void FromARGB(CKDWORD argb) { a = ((argb & 0xFF000000) >> 24) / 255.0f; @@ -431,6 +432,7 @@ namespace LibCmo::VxMath { if (a > 1.0f) a = 1.0f; else if (a < 0.0f) a = 0.0f; } + // ===== END USER CUSTOM ===== }; /** @@ -446,10 +448,6 @@ namespace LibCmo::VxMath { VxMatrix() : m_Data() { ResetToIdentity(); } VxMatrix(CKFLOAT m[4][4]) : m_Data() { std::memcpy(m_Data, m, sizeof(m_Data)); } YYCC_DEF_CLS_COPY_MOVE(VxMatrix); - void ResetToIdentity() { - std::memset(m_Data, 0, sizeof(m_Data)); - m_Data[0][0] = m_Data[1][1] = m_Data[2][2] = m_Data[3][3] = 1.0f; - } VxVector4& operator[](size_t i) { if (i >= 4) throw LogicException("Invalid index for VxMatrix::operator[]."); return *(reinterpret_cast(m_Data) + i); @@ -461,8 +459,20 @@ namespace LibCmo::VxMath { bool operator==(const VxMatrix& rhs) const { return std::memcmp(m_Data, rhs.m_Data, sizeof(m_Data)) == 0; } + + // ===== BEGIN USER CUSTOM ===== + void ResetToIdentity() { + Clear(); + m_Data[0][0] = m_Data[1][1] = m_Data[2][2] = m_Data[3][3] = 1.0f; + } + void Clear() { + std::memset(m_Data, 0, sizeof(m_Data)); + } + // ===== END USER CUSTOM ===== }; + // ========== Misc ========== + /** * @brief Structure for storage of strided data. * @tparam _Ty The data pointer type this class stored. @@ -698,4 +708,157 @@ namespace LibCmo::VxMath { CKBYTE* m_Image; /**< A pointer points to current image in memory */ }; + // ========== Patch Section ========== + + /** + * @brief The patch namespace for VxVector-like classes + * @details This namespace provides VxVector-like classes member functions which presented in original Virtools SDK. + * These functions are put in public namespace in original Virtools SDK. + * We just organise them into an unique namespace. + */ + namespace NSVxVector { + + /** + * @brief Dot product 2 2d vectors. + * @param[in] lhs The left side vector of dot product symbol. + * @param[in] rhs The right side vector of dot product symbol. + * @return The float pointing result of dot product. + */ + CKFLOAT DotProduct(const VxVector2& lhs, const VxVector2& rhs); + /** + * @brief Dot product 2 3d vectors. + * @param[in] lhs The left side vector of dot product symbol. + * @param[in] rhs The right side vector of dot product symbol. + * @return The float pointing result of dot product. + */ + CKFLOAT DotProduct(const VxVector3& lhs, const VxVector3& rhs); + /** + * @brief Dot product 2 4d vectors. + * @param[in] lhs The left side vector of dot product symbol. + * @param[in] rhs The right side vector of dot product symbol. + * @return The float pointing result of dot product. + */ + CKFLOAT DotProduct(const VxVector4& lhs, const VxVector4& rhs); + + /** + * @brief Cross product 2 3d vectors. + * @param[in] lhs The left side vector of cross product symbol. + * @param[in] rhs The right side vector of cross product symbol. + * @return The 3d vector result of cross product. + */ + VxVector3 CrossProduct(const VxVector3& lhs, const VxVector3& rhs); + + /** + * @brief Set all factor in vector to its absolute value. + * @param[in,out] lhs The vector for processing. + * @remarks This function is rarely used. + * Please note this function is not calculate the absolute value of vector. + */ + void Abs(VxVector3& lhs); + + } + + /** + * @brief The patch namespace for VxMatrix classes + * @details Like NXVxVector, these functions located in this namespace + * are exposed in public namespace in original Virtools SDK. + * And I re-organise them in there. + */ + namespace NSVxMatrix { + + /** + * @brief Constructs a perspective projection matrix. + * @param[in] Fov Field of View. + * @param[in] Aspect Aspect ratio (Width/height) + * @param[in] Near_plane Distance of the near clipping plane. + * @param[in] Far_plane Distance of the far clipping plane. + * @remarks Sets Mat to + * + * A = Cos(Fov/2)/Sin(Fov/2) + * F = Far_plane + * N = Near_plane + * + * [ A 0 0 0] + * [ 0 A*Aspect 0 0] + * MAT= [ 0 0 F/F-N 1] + * [ 0 0 -F.N/F-N 0] + * + * @see PerspectiveRect, Orthographic, OrthographicRect + */ + void Perspective(VxMatrix& mat, float Fov, float Aspect, float Near_plane, float Far_plane); + + /** + * @brief Constructs a perspective projection matrix given a view rectangle. + * @param[in] Left Left clipping plane value. + * @param[in] Right Right clipping plane value. + * @param[in] Top top clipping plane value. + * @param[in] Bottom bottom clipping plane value. + * @param[in] Near_plane Distance of the near clipping plane. + * @param[in] Far_plane Distance of the far clipping plane. + * @remarks Sets Mat to + * + * F = Far_plane + * N = Near_plane + * R = Right + * L = Left + * T = Top + * B = Bottom + * + * [ 2/(R-L) 0 0 0] + * [ 0 -2/(T-B) 0 0] + * MAT = [ 0 0 1/F-N 0] + * [ -(L+R)/(R-L) (T+B)/(T-B) -N/F-N 1] + * + * @see Perspective, Orthographic, OrthographicRect + */ + void PerspectiveRect(VxMatrix& mat, float Left, float Right, float Top, float Bottom, float Near_plane, float Far_plane); + + /** + * @brief Constructs a orthographic projection matrix. + * @param[in] Zoom Zoom factor. + * @param[in] Aspect Aspect ratio (Width/height) + * @param[in] Near_plane Distance of the near clipping plane. + * @param[in] Far_plane Distance of the far clipping plane. + * @remarks Sets Mat to + * + * F = Far_plane + * N = Near_plane + * + * [ Zoom 0 0 0] + * [ 0 Zoom*Aspect 0 0] + * MAT = [ 0 0 1/F-N 0] + * [ 0 0 -N/F-N 1] + * + * @see Perspective, OrthographicRect + */ + void Orthographic(VxMatrix& mat, float Zoom, float Aspect, float Near_plane, float Far_plane); + + /** + * @brief Constructs a orthographic projection matrix. + * @param[in] Left Left clipping plane value. + * @param[in] Right Right clipping plane value. + * @param[in] Top top clipping plane value. + * @param[in] Bottom bottom clipping plane value. + * @param[in] Near_plane Distance of the near clipping plane. + * @param[in] Far_plane Distance of the far clipping plane. + * @remarks Sets Mat to + * + * F = Far_plane + * N = Near_plane + * R = Right + * L = Left + * T = Top + * B = Bottom + * + * [ 2/(R-L) 0 0 0] + * [ 0 -2/(T-B) 0 0] + * MAT = [ 0 0 1/F-N 0] + * [ -(L+R)/(R-L) (T+B)/(T-B) -N/F-N 1] + * + * @see Perspective, Orthographic + */ + void OrthographicRect(VxMatrix& mat, float Left, float Right, float Top, float Bottom, float Near_plane, float Far_plane); + + } + }