mirror of
https://github.com/godotengine/godot.git
synced 2024-11-22 04:06:14 +00:00
create vector4, vector4i and projection for csharp
This commit is contained in:
parent
7686cfec64
commit
87ebfff46d
39
.github/workflows/linux_builds.yml
vendored
39
.github/workflows/linux_builds.yml
vendored
@ -19,30 +19,15 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
# Temporarily disabled until Mono is fixed
|
||||
#
|
||||
# - name: Editor w Mono (target=release_debug, tools=yes, tests=yes)
|
||||
# cache-name: linux-editor-mono
|
||||
# target: release_debug
|
||||
# tools: true
|
||||
# tests: false # Disabled due freeze caused by mix Mono build and CI
|
||||
# sconsflags: module_mono_enabled=yes mono_static=yes mono_glue=no
|
||||
# doc-test: true
|
||||
# bin: "./bin/godot.linuxbsd.opt.tools.64.mono"
|
||||
# build-mono: true
|
||||
# proj-conv: true
|
||||
# artifact: true
|
||||
|
||||
# Temporary replacement:
|
||||
|
||||
- name: Editor w/o Mono (target=release_debug, tools=yes, tests=yes)
|
||||
- name: Editor w Mono (target=release_debug, tools=yes, tests=yes)
|
||||
cache-name: linux-editor-mono
|
||||
target: release_debug
|
||||
tools: true
|
||||
tests: false # Disabled due freeze caused by mix Mono build and CI
|
||||
sconsflags: module_mono_enabled=yes mono_static=yes mono_glue=no
|
||||
doc-test: true
|
||||
bin: "./bin/godot.linuxbsd.opt.tools.64"
|
||||
build-mono: false
|
||||
bin: "./bin/godot.linuxbsd.opt.tools.64.mono"
|
||||
build-mono: true
|
||||
proj-conv: true
|
||||
artifact: true
|
||||
|
||||
@ -72,24 +57,12 @@ jobs:
|
||||
# Skip 2GiB artifact speeding up action.
|
||||
artifact: false
|
||||
|
||||
# Temporarily disabled:
|
||||
#
|
||||
# - name: Template w/ Mono (target=release, tools=no)
|
||||
# cache-name: linux-template-mono
|
||||
# target: release
|
||||
# tools: false
|
||||
# tests: false
|
||||
# sconsflags: module_mono_enabled=yes mono_static=yes mono_glue=no debug_symbols=no
|
||||
# build-mono: false
|
||||
# artifact: true
|
||||
|
||||
# Temporary replacement:
|
||||
|
||||
- name: Template w/o Mono (target=release, tools=no)
|
||||
- name: Template w/ Mono (target=release, tools=no)
|
||||
cache-name: linux-template-mono
|
||||
target: release
|
||||
tools: false
|
||||
tests: false
|
||||
sconsflags: module_mono_enabled=yes mono_static=yes mono_glue=no debug_symbols=no
|
||||
build-mono: false
|
||||
artifact: true
|
||||
|
||||
|
820
modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs
Normal file
820
modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs
Normal file
@ -0,0 +1,820 @@
|
||||
#if REAL_T_IS_DOUBLE
|
||||
using real_t = System.Double;
|
||||
#else
|
||||
using real_t = System.Single;
|
||||
#endif
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Godot
|
||||
{
|
||||
[Serializable]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Projection : IEquatable<Projection>
|
||||
{
|
||||
/// <summary>
|
||||
/// Enumerated index values for the planes.
|
||||
/// </summary>
|
||||
public enum Planes
|
||||
{
|
||||
/// <summary>
|
||||
/// The projection's near plane.
|
||||
/// </summary>
|
||||
Near,
|
||||
/// <summary>
|
||||
/// The projection's far plane.
|
||||
/// </summary>
|
||||
Far,
|
||||
/// <summary>
|
||||
/// The projection's left plane.
|
||||
/// </summary>
|
||||
Left,
|
||||
/// <summary>
|
||||
/// The projection's top plane.
|
||||
/// </summary>
|
||||
Top,
|
||||
/// <summary>
|
||||
/// The projection's right plane.
|
||||
/// </summary>
|
||||
Right,
|
||||
/// <summary>
|
||||
/// The projection's bottom plane.
|
||||
/// </summary>
|
||||
Bottom,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The projections's X column. Also accessible by using the index position <c>[0]</c>.
|
||||
/// </summary>
|
||||
public Vector4 x;
|
||||
|
||||
/// <summary>
|
||||
/// The projections's Y column. Also accessible by using the index position <c>[1]</c>.
|
||||
/// </summary>
|
||||
public Vector4 y;
|
||||
|
||||
/// <summary>
|
||||
/// The projections's Z column. Also accessible by using the index position <c>[2]</c>.
|
||||
/// </summary>
|
||||
public Vector4 z;
|
||||
|
||||
/// <summary>
|
||||
/// The projections's W column. Also accessible by using the index position <c>[3]</c>.
|
||||
/// </summary>
|
||||
public Vector4 w;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a projection from 4 vectors (matrix columns).
|
||||
/// </summary>
|
||||
/// <param name="x">The X column, or column index 0.</param>
|
||||
/// <param name="y">The Y column, or column index 1.</param>
|
||||
/// <param name="z">The Z column, or column index 2.</param>
|
||||
/// <param name="w">The W column, or column index 3.</param>
|
||||
public Projection(Vector4 x, Vector4 y, Vector4 z, Vector4 w)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.w = w;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="Projection"/> from an existing <see cref="Projection"/>.
|
||||
/// </summary>
|
||||
/// <param name="proj">The existing <see cref="Projection"/>.</param>
|
||||
public Projection(Projection proj)
|
||||
{
|
||||
x = proj.x;
|
||||
y = proj.y;
|
||||
z = proj.z;
|
||||
w = proj.w;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="Projection"/> from a <see cref="Transform3D"/>.
|
||||
/// </summary>
|
||||
/// <param name="transform">The <see cref="Transform3D"/>.</param>
|
||||
public Projection(Transform3D transform)
|
||||
{
|
||||
x = new Vector4(transform.basis.Row0.x, transform.basis.Row1.x, transform.basis.Row2.x, 0);
|
||||
y = new Vector4(transform.basis.Row0.y, transform.basis.Row1.y, transform.basis.Row2.y, 0);
|
||||
z = new Vector4(transform.basis.Row0.z, transform.basis.Row1.z, transform.basis.Row2.z, 0);
|
||||
w = new Vector4(transform.origin.x, transform.origin.y, transform.origin.z, 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="Transform3D"/> from the <see cref="Projection"/>.
|
||||
/// </summary>
|
||||
/// <param name="proj">The <see cref="Projection"/>.</param>
|
||||
public static explicit operator Transform3D(Projection proj)
|
||||
{
|
||||
return new Transform3D(
|
||||
new Basis(
|
||||
new Vector3(proj.x.x, proj.x.y, proj.x.z),
|
||||
new Vector3(proj.y.x, proj.y.y, proj.y.z),
|
||||
new Vector3(proj.z.x, proj.z.y, proj.z.z)
|
||||
),
|
||||
new Vector3(proj.w.x, proj.w.y, proj.w.z)
|
||||
);
|
||||
}
|
||||
|
||||
public static Projection CreateDepthCorrection(bool flipY)
|
||||
{
|
||||
return new Projection(
|
||||
new Vector4(1, 0, 0, 0),
|
||||
new Vector4(0, flipY ? -1 : 1, 0, 0),
|
||||
new Vector4(0, 0, (real_t)0.5, 0),
|
||||
new Vector4(0, 0, (real_t)0.5, 1)
|
||||
);
|
||||
}
|
||||
|
||||
public static Projection CreateFitAabb(AABB aabb)
|
||||
{
|
||||
Vector3 min = aabb.Position;
|
||||
Vector3 max = aabb.Position + aabb.Size;
|
||||
|
||||
return new Projection(
|
||||
new Vector4(2 / (max.x - min.x), 0, 0, 0),
|
||||
new Vector4(0, 2 / (max.y - min.y), 0, 0),
|
||||
new Vector4(0, 0, 2 / (max.z - min.z), 0),
|
||||
new Vector4(-(max.x + min.x) / (max.x - min.x), -(max.y + min.y) / (max.y - min.y), -(max.z + min.z) / (max.z - min.z), 1)
|
||||
);
|
||||
}
|
||||
|
||||
public static Projection CreateForHmd(int eye, real_t aspect, real_t intraocularDist, real_t displayWidth, real_t displayToLens, real_t oversample, real_t zNear, real_t zFar)
|
||||
{
|
||||
real_t f1 = (intraocularDist * (real_t)0.5) / displayToLens;
|
||||
real_t f2 = ((displayWidth - intraocularDist) * (real_t)0.5) / displayToLens;
|
||||
real_t f3 = (displayWidth / (real_t)4.0) / displayToLens;
|
||||
|
||||
real_t add = ((f1 + f2) * (oversample - (real_t)1.0)) / (real_t)2.0;
|
||||
f1 += add;
|
||||
f2 += add;
|
||||
f3 *= oversample;
|
||||
|
||||
f3 /= aspect;
|
||||
|
||||
switch (eye)
|
||||
{
|
||||
case 1:
|
||||
return CreateFrustum(-f2 * zNear, f1 * zNear, -f3 * zNear, f3 * zNear, zNear, zFar);
|
||||
case 2:
|
||||
return CreateFrustum(-f1 * zNear, f2 * zNear, -f3 * zNear, f3 * zNear, zNear, zFar);
|
||||
default:
|
||||
return Zero;
|
||||
}
|
||||
}
|
||||
|
||||
public static Projection CreateFrustum(real_t left, real_t right, real_t bottom, real_t top, real_t near, real_t far)
|
||||
{
|
||||
if (right <= left)
|
||||
{
|
||||
throw new ArgumentException("right is less or equal to left.");
|
||||
}
|
||||
if (top <= bottom)
|
||||
{
|
||||
throw new ArgumentException("top is less or equal to bottom.");
|
||||
}
|
||||
if (far <= near)
|
||||
{
|
||||
throw new ArgumentException("far is less or equal to near.");
|
||||
}
|
||||
|
||||
real_t x = 2 * near / (right - left);
|
||||
real_t y = 2 * near / (top - bottom);
|
||||
|
||||
real_t a = (right + left) / (right - left);
|
||||
real_t b = (top + bottom) / (top - bottom);
|
||||
real_t c = -(far + near) / (far - near);
|
||||
real_t d = -2 * far * near / (far - near);
|
||||
|
||||
return new Projection(
|
||||
new Vector4(x, 0, 0, 0),
|
||||
new Vector4(0, y, 0, 0),
|
||||
new Vector4(a, b, c, -1),
|
||||
new Vector4(0, 0, d, 0)
|
||||
);
|
||||
}
|
||||
|
||||
public static Projection CreateFrustumAspect(real_t size, real_t aspect, Vector2 offset, real_t near, real_t far, bool flipFov)
|
||||
{
|
||||
if (!flipFov)
|
||||
{
|
||||
size *= aspect;
|
||||
}
|
||||
return CreateFrustum(-size / 2 + offset.x, +size / 2 + offset.x, -size / aspect / 2 + offset.y, +size / aspect / 2 + offset.y, near, far);
|
||||
}
|
||||
|
||||
public static Projection CreateLightAtlasRect(Rect2 rect)
|
||||
{
|
||||
return new Projection(
|
||||
new Vector4(rect.Size.x, 0, 0, 0),
|
||||
new Vector4(0, rect.Size.y, 0, 0),
|
||||
new Vector4(0, 0, 1, 0),
|
||||
new Vector4(rect.Position.x, rect.Position.y, 0, 1)
|
||||
);
|
||||
}
|
||||
|
||||
public static Projection CreateOrthogonal(real_t left, real_t right, real_t bottom, real_t top, real_t zNear, real_t zFar)
|
||||
{
|
||||
Projection proj = Projection.Identity;
|
||||
proj.x.x = (real_t)2.0 / (right - left);
|
||||
proj.w.x = -((right + left) / (right - left));
|
||||
proj.y.y = (real_t)2.0 / (top - bottom);
|
||||
proj.w.y = -((top + bottom) / (top - bottom));
|
||||
proj.z.z = (real_t)(-2.0) / (zFar - zNear);
|
||||
proj.w.z = -((zFar + zNear) / (zFar - zNear));
|
||||
proj.w.w = (real_t)1.0;
|
||||
return proj;
|
||||
}
|
||||
|
||||
public static Projection CreateOrthogonalAspect(real_t size, real_t aspect, real_t zNear, real_t zFar, bool flipFov)
|
||||
{
|
||||
if (!flipFov)
|
||||
{
|
||||
size *= aspect;
|
||||
}
|
||||
return CreateOrthogonal(-size / 2, +size / 2, -size / aspect / 2, +size / aspect / 2, zNear, zFar);
|
||||
}
|
||||
|
||||
public static Projection CreatePerspective(real_t fovyDegrees, real_t aspect, real_t zNear, real_t zFar, bool flipFov)
|
||||
{
|
||||
if (flipFov)
|
||||
{
|
||||
fovyDegrees = GetFovy(fovyDegrees, (real_t)1.0 / aspect);
|
||||
}
|
||||
real_t radians = Mathf.Deg2Rad(fovyDegrees / (real_t)2.0);
|
||||
real_t deltaZ = zFar - zNear;
|
||||
real_t sine = Mathf.Sin(radians);
|
||||
|
||||
if ((deltaZ == 0) || (sine == 0) || (aspect == 0))
|
||||
{
|
||||
return Zero;
|
||||
}
|
||||
|
||||
real_t cotangent = Mathf.Cos(radians) / sine;
|
||||
|
||||
Projection proj = Projection.Identity;
|
||||
|
||||
proj.x.x = cotangent / aspect;
|
||||
proj.y.y = cotangent;
|
||||
proj.z.z = -(zFar + zNear) / deltaZ;
|
||||
proj.z.w = -1;
|
||||
proj.w.z = -2 * zNear * zFar / deltaZ;
|
||||
proj.w.w = 0;
|
||||
|
||||
return proj;
|
||||
}
|
||||
|
||||
public static Projection CreatePerspectiveHmd(real_t fovyDegrees, real_t aspect, real_t zNear, real_t zFar, bool flipFov, int eye, real_t intraocularDist, real_t convergenceDist)
|
||||
{
|
||||
if (flipFov)
|
||||
{
|
||||
fovyDegrees = GetFovy(fovyDegrees, (real_t)1.0 / aspect);
|
||||
}
|
||||
|
||||
real_t ymax = zNear * Mathf.Tan(Mathf.Deg2Rad(fovyDegrees / (real_t)2.0));
|
||||
real_t xmax = ymax * aspect;
|
||||
real_t frustumshift = (intraocularDist / (real_t)2.0) * zNear / convergenceDist;
|
||||
real_t left;
|
||||
real_t right;
|
||||
real_t modeltranslation;
|
||||
switch (eye)
|
||||
{
|
||||
case 1:
|
||||
left = -xmax + frustumshift;
|
||||
right = xmax + frustumshift;
|
||||
modeltranslation = intraocularDist / (real_t)2.0;
|
||||
break;
|
||||
case 2:
|
||||
left = -xmax - frustumshift;
|
||||
right = xmax - frustumshift;
|
||||
modeltranslation = -intraocularDist / (real_t)2.0;
|
||||
break;
|
||||
default:
|
||||
left = -xmax;
|
||||
right = xmax;
|
||||
modeltranslation = (real_t)0.0;
|
||||
break;
|
||||
}
|
||||
Projection proj = CreateFrustum(left, right, -ymax, ymax, zNear, zFar);
|
||||
Projection cm = Projection.Identity;
|
||||
cm.w.x = modeltranslation;
|
||||
return proj * cm;
|
||||
}
|
||||
|
||||
public real_t Determinant()
|
||||
{
|
||||
return x.w * y.z * z.y * w.x - x.z * y.w * z.y * w.x -
|
||||
x.w * y.y * z.z * w.x + x.y * y.w * z.z * w.x +
|
||||
x.z * y.y * z.w * w.x - x.y * y.z * z.w * w.x -
|
||||
x.w * y.z * z.x * w.y + x.z * y.w * z.x * w.y +
|
||||
x.w * y.x * z.z * w.y - x.x * y.w * z.z * w.y -
|
||||
x.z * y.x * z.w * w.y + x.x * y.z * z.w * w.y +
|
||||
x.w * y.y * z.x * w.z - x.y * y.w * z.x * w.z -
|
||||
x.w * y.x * z.y * w.z + x.x * y.w * z.y * w.z +
|
||||
x.y * y.x * z.w * w.z - x.x * y.y * z.w * w.z -
|
||||
x.z * y.y * z.x * w.w + x.y * y.z * z.x * w.w +
|
||||
x.z * y.x * z.y * w.w - x.x * y.z * z.y * w.w -
|
||||
x.y * y.x * z.z * w.w + x.x * y.y * z.z * w.w;
|
||||
}
|
||||
|
||||
public real_t GetAspect()
|
||||
{
|
||||
Vector2 vpHe = GetViewportHalfExtents();
|
||||
return vpHe.x / vpHe.y;
|
||||
}
|
||||
|
||||
public real_t GetFov()
|
||||
{
|
||||
Plane rightPlane = new Plane(x.w - x.x, y.w - y.x, z.w - z.x, -w.w + w.x).Normalized();
|
||||
if (z.x == 0 && z.y == 0)
|
||||
{
|
||||
return Mathf.Rad2Deg(Mathf.Acos(Mathf.Abs(rightPlane.Normal.x))) * (real_t)2.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Plane leftPlane = new Plane(x.w + x.x, y.w + y.x, z.w + z.x, w.w + w.x).Normalized();
|
||||
return Mathf.Rad2Deg(Mathf.Acos(Mathf.Abs(leftPlane.Normal.x))) + Mathf.Rad2Deg(Mathf.Acos(Mathf.Abs(rightPlane.Normal.x)));
|
||||
}
|
||||
}
|
||||
|
||||
public static real_t GetFovy(real_t fovx, real_t aspect)
|
||||
{
|
||||
return Mathf.Rad2Deg(Mathf.Atan(aspect * Mathf.Tan(Mathf.Deg2Rad(fovx) * (real_t)0.5)) * (real_t)2.0);
|
||||
}
|
||||
|
||||
public real_t GetLodMultiplier()
|
||||
{
|
||||
if (IsOrthogonal())
|
||||
{
|
||||
return GetViewportHalfExtents().x;
|
||||
}
|
||||
else
|
||||
{
|
||||
real_t zn = GetZNear();
|
||||
real_t width = GetViewportHalfExtents().x * (real_t)2.0;
|
||||
return (real_t)1.0 / (zn / width);
|
||||
}
|
||||
}
|
||||
|
||||
public int GetPixelsPerMeter(int forPixelWidth)
|
||||
{
|
||||
Vector3 result = Xform(new Vector3(1, 0, -1));
|
||||
|
||||
return (int)((result.x * (real_t)0.5 + (real_t)0.5) * forPixelWidth);
|
||||
}
|
||||
|
||||
public Plane GetProjectionPlane(Planes plane)
|
||||
{
|
||||
Plane newPlane = plane switch
|
||||
{
|
||||
Planes.Near => new Plane(x.w + x.z, y.w + y.z, z.w + z.z, w.w + w.z),
|
||||
Planes.Far => new Plane(x.w - x.z, y.w - y.z, z.w - z.z, w.w - w.z),
|
||||
Planes.Left => new Plane(x.w + x.x, y.w + y.x, z.w + z.x, w.w + w.x),
|
||||
Planes.Top => new Plane(x.w - x.y, y.w - y.y, z.w - z.y, w.w - w.y),
|
||||
Planes.Right => new Plane(x.w - x.x, y.w - y.x, z.w - z.x, w.w - w.x),
|
||||
Planes.Bottom => new Plane(x.w + x.y, y.w + y.y, z.w + z.y, w.w + w.y),
|
||||
_ => new Plane(),
|
||||
};
|
||||
newPlane.Normal = -newPlane.Normal;
|
||||
return newPlane.Normalized();
|
||||
}
|
||||
|
||||
public Vector2 GetFarPlaneHalfExtents()
|
||||
{
|
||||
var res = GetProjectionPlane(Planes.Far).Intersect3(GetProjectionPlane(Planes.Right), GetProjectionPlane(Planes.Top));
|
||||
return new Vector2(res.Value.x, res.Value.y);
|
||||
}
|
||||
|
||||
public Vector2 GetViewportHalfExtents()
|
||||
{
|
||||
var res = GetProjectionPlane(Planes.Near).Intersect3(GetProjectionPlane(Planes.Right), GetProjectionPlane(Planes.Top));
|
||||
return new Vector2(res.Value.x, res.Value.y);
|
||||
}
|
||||
|
||||
public real_t GetZFar()
|
||||
{
|
||||
return GetProjectionPlane(Planes.Far).D;
|
||||
}
|
||||
|
||||
public real_t GetZNear()
|
||||
{
|
||||
return -GetProjectionPlane(Planes.Near).D;
|
||||
}
|
||||
|
||||
public Projection FlippedY()
|
||||
{
|
||||
Projection proj = this;
|
||||
proj.y = -proj.y;
|
||||
return proj;
|
||||
}
|
||||
|
||||
public Projection PerspectiveZNearAdjusted(real_t newZNear)
|
||||
{
|
||||
Projection proj = this;
|
||||
real_t zFar = GetZFar();
|
||||
real_t zNear = newZNear;
|
||||
real_t deltaZ = zFar - zNear;
|
||||
proj.z.z = -(zFar + zNear) / deltaZ;
|
||||
proj.w.z = -2 * zNear * zFar / deltaZ;
|
||||
return proj;
|
||||
}
|
||||
|
||||
public Projection JitterOffseted(Vector2 offset)
|
||||
{
|
||||
Projection proj = this;
|
||||
proj.w.x += offset.x;
|
||||
proj.w.y += offset.y;
|
||||
return proj;
|
||||
}
|
||||
|
||||
public Projection Inverse()
|
||||
{
|
||||
Projection proj = this;
|
||||
int i, j, k;
|
||||
int[] pvt_i = new int[4];
|
||||
int[] pvt_j = new int[4]; /* Locations of pivot matrix */
|
||||
real_t pvt_val; /* Value of current pivot element */
|
||||
real_t hold; /* Temporary storage */
|
||||
real_t determinant = 1.0f;
|
||||
for (k = 0; k < 4; k++)
|
||||
{
|
||||
/* Locate k'th pivot element */
|
||||
pvt_val = proj[k][k]; /* Initialize for search */
|
||||
pvt_i[k] = k;
|
||||
pvt_j[k] = k;
|
||||
for (i = k; i < 4; i++)
|
||||
{
|
||||
for (j = k; j < 4; j++)
|
||||
{
|
||||
if (Mathf.Abs(proj[i][j]) > Mathf.Abs(pvt_val))
|
||||
{
|
||||
pvt_i[k] = i;
|
||||
pvt_j[k] = j;
|
||||
pvt_val = proj[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Product of pivots, gives determinant when finished */
|
||||
determinant *= pvt_val;
|
||||
if (Mathf.IsZeroApprox(determinant))
|
||||
{
|
||||
return Zero;
|
||||
}
|
||||
|
||||
/* "Interchange" rows (with sign change stuff) */
|
||||
i = pvt_i[k];
|
||||
if (i != k)
|
||||
{ /* If rows are different */
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
hold = -proj[k][j];
|
||||
proj[k, j] = proj[i][j];
|
||||
proj[i, j] = hold;
|
||||
}
|
||||
}
|
||||
|
||||
/* "Interchange" columns */
|
||||
j = pvt_j[k];
|
||||
if (j != k)
|
||||
{ /* If columns are different */
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
hold = -proj[i][k];
|
||||
proj[i, k] = proj[i][j];
|
||||
proj[i, j] = hold;
|
||||
}
|
||||
}
|
||||
|
||||
/* Divide column by minus pivot value */
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (i != k)
|
||||
{
|
||||
proj[i, k] /= (-pvt_val);
|
||||
}
|
||||
}
|
||||
|
||||
/* Reduce the matrix */
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
hold = proj[i][k];
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
if (i != k && j != k)
|
||||
{
|
||||
proj[i, j] += hold * proj[k][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Divide row by pivot */
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
if (j != k)
|
||||
{
|
||||
proj[k, j] /= pvt_val;
|
||||
}
|
||||
}
|
||||
|
||||
/* Replace pivot by reciprocal (at last we can touch it). */
|
||||
proj[k, k] = (real_t)1.0 / pvt_val;
|
||||
}
|
||||
|
||||
/* That was most of the work, one final pass of row/column interchange */
|
||||
/* to finish */
|
||||
for (k = 4 - 2; k >= 0; k--)
|
||||
{ /* Don't need to work with 1 by 1 corner*/
|
||||
i = pvt_j[k]; /* Rows to swap correspond to pivot COLUMN */
|
||||
if (i != k)
|
||||
{ /* If rows are different */
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
hold = proj[k][j];
|
||||
proj[k, j] = -proj[i][j];
|
||||
proj[i, j] = hold;
|
||||
}
|
||||
}
|
||||
|
||||
j = pvt_i[k]; /* Columns to swap correspond to pivot ROW */
|
||||
if (j != k)
|
||||
{ /* If columns are different */
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
hold = proj[i][k];
|
||||
proj[i, k] = -proj[i][j];
|
||||
proj[i, j] = hold;
|
||||
}
|
||||
}
|
||||
}
|
||||
return proj;
|
||||
}
|
||||
|
||||
public bool IsOrthogonal()
|
||||
{
|
||||
return w.w == (real_t)1.0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Composes these two projections by multiplying them
|
||||
/// together. This has the effect of applying the right
|
||||
/// and then the left projection.
|
||||
/// </summary>
|
||||
/// <param name="left">The parent transform.</param>
|
||||
/// <param name="right">The child transform.</param>
|
||||
/// <returns>The composed projection.</returns>
|
||||
public static Projection operator *(Projection left, Projection right)
|
||||
{
|
||||
return new Projection(
|
||||
new Vector4(
|
||||
left.x.x * right.x.x + left.y.x * right.x.y + left.z.x * right.x.z + left.w.x * right.x.w,
|
||||
left.x.y * right.x.x + left.y.y * right.x.y + left.z.y * right.x.z + left.w.y * right.x.w,
|
||||
left.x.z * right.x.x + left.y.z * right.x.y + left.z.z * right.x.z + left.w.z * right.x.w,
|
||||
left.x.w * right.x.x + left.y.w * right.x.y + left.z.w * right.x.z + left.w.w * right.x.w
|
||||
), new Vector4(
|
||||
left.x.x * right.y.x + left.y.x * right.y.y + left.z.x * right.y.z + left.w.x * right.y.w,
|
||||
left.x.y * right.y.x + left.y.y * right.y.y + left.z.y * right.y.z + left.w.y * right.y.w,
|
||||
left.x.z * right.y.x + left.y.z * right.y.y + left.z.z * right.y.z + left.w.z * right.y.w,
|
||||
left.x.w * right.y.x + left.y.w * right.y.y + left.z.w * right.y.z + left.w.w * right.y.w
|
||||
), new Vector4(
|
||||
left.x.x * right.z.x + left.y.x * right.z.y + left.z.x * right.z.z + left.w.x * right.z.w,
|
||||
left.x.y * right.z.x + left.y.y * right.z.y + left.z.y * right.z.z + left.w.y * right.z.w,
|
||||
left.x.z * right.z.x + left.y.z * right.z.y + left.z.z * right.z.z + left.w.z * right.z.w,
|
||||
left.x.w * right.z.x + left.y.w * right.z.y + left.z.w * right.z.z + left.w.w * right.z.w
|
||||
), new Vector4(
|
||||
left.x.x * right.w.x + left.y.x * right.w.y + left.z.x * right.w.z + left.w.x * right.w.w,
|
||||
left.x.y * right.w.x + left.y.y * right.w.y + left.z.y * right.w.z + left.w.y * right.w.w,
|
||||
left.x.z * right.w.x + left.y.z * right.w.y + left.z.z * right.w.z + left.w.z * right.w.w,
|
||||
left.x.w * right.w.x + left.y.w * right.w.y + left.z.w * right.w.z + left.w.w * right.w.w
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a vector transformed (multiplied) by this projection.
|
||||
/// </summary>
|
||||
/// <param name="proj">The projection to apply.</param>
|
||||
/// <param name="v">A vector to transform.</param>
|
||||
/// <returns>The transformed vector.</returns>
|
||||
public static Vector4 operator *(Projection proj, Vector4 v)
|
||||
{
|
||||
return new Vector4(
|
||||
proj.x.x * v.x + proj.y.x * v.y + proj.z.x * v.z + proj.w.x * v.w,
|
||||
proj.x.y * v.x + proj.y.y * v.y + proj.z.y * v.z + proj.w.y * v.w,
|
||||
proj.x.z * v.x + proj.y.z * v.y + proj.z.z * v.z + proj.w.z * v.w,
|
||||
proj.x.w * v.x + proj.y.w * v.y + proj.z.w * v.z + proj.w.w * v.w
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns <see langword="true"/> if the projections are exactly equal.
|
||||
/// </summary>
|
||||
/// <param name="left">The left projection.</param>
|
||||
/// <param name="right">The right projection.</param>
|
||||
/// <returns>Whether or not the projections are exactly equal.</returns>
|
||||
public static bool operator ==(Projection left, Projection right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns <see langword="true"/> if the projections are not exactly equal.
|
||||
/// </summary>
|
||||
/// <param name="left">The left projection.</param>
|
||||
/// <param name="right">The right projection.</param>
|
||||
/// <returns>Whether or not the projections are not exactly equal.</returns>
|
||||
public static bool operator !=(Projection left, Projection right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Access whole columns in the form of <see cref="Vector4"/>.
|
||||
/// </summary>
|
||||
/// <param name="column">Which column vector.</param>
|
||||
public Vector4 this[int column]
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (column)
|
||||
{
|
||||
case 0:
|
||||
return x;
|
||||
case 1:
|
||||
return y;
|
||||
case 2:
|
||||
return z;
|
||||
case 3:
|
||||
return w;
|
||||
default:
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
switch (column)
|
||||
{
|
||||
case 0:
|
||||
x = value;
|
||||
return;
|
||||
case 1:
|
||||
y = value;
|
||||
return;
|
||||
case 2:
|
||||
z = value;
|
||||
return;
|
||||
case 3:
|
||||
w = value;
|
||||
return;
|
||||
default:
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Access single values.
|
||||
/// </summary>
|
||||
/// <param name="column">Which column vector.</param>
|
||||
/// <param name="row">Which row of the column.</param>
|
||||
public real_t this[int column, int row]
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (column)
|
||||
{
|
||||
case 0:
|
||||
return x[row];
|
||||
case 1:
|
||||
return y[row];
|
||||
case 2:
|
||||
return z[row];
|
||||
case 3:
|
||||
return w[row];
|
||||
default:
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
switch (column)
|
||||
{
|
||||
case 0:
|
||||
x[row] = value;
|
||||
return;
|
||||
case 1:
|
||||
y[row] = value;
|
||||
return;
|
||||
case 2:
|
||||
z[row] = value;
|
||||
return;
|
||||
case 3:
|
||||
w[row] = value;
|
||||
return;
|
||||
default:
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a vector transformed (multiplied) by this projection.
|
||||
/// </summary>
|
||||
/// <param name="v">A vector to transform.</param>
|
||||
/// <returns>The transformed vector.</returns>
|
||||
private Vector3 Xform(Vector3 v)
|
||||
{
|
||||
Vector3 ret = new Vector3(
|
||||
x.x * v.x + y.x * v.y + z.x * v.z + w.x,
|
||||
x.y * v.x + y.y * v.y + z.y * v.z + w.y,
|
||||
x.z * v.x + y.z * v.y + z.z * v.z + w.z
|
||||
);
|
||||
return ret / (x.w * v.x + y.w * v.y + z.w * v.z + w.w);
|
||||
}
|
||||
|
||||
// Constants
|
||||
private static readonly Projection _zero = new Projection(
|
||||
new Vector4(0, 0, 0, 0),
|
||||
new Vector4(0, 0, 0, 0),
|
||||
new Vector4(0, 0, 0, 0),
|
||||
new Vector4(0, 0, 0, 0)
|
||||
);
|
||||
private static readonly Projection _identity = new Projection(
|
||||
new Vector4(1, 0, 0, 0),
|
||||
new Vector4(0, 1, 0, 0),
|
||||
new Vector4(0, 0, 1, 0),
|
||||
new Vector4(0, 0, 0, 1)
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Zero projection, a projection with all components set to <c>0</c>.
|
||||
/// </summary>
|
||||
/// <value>Equivalent to <c>new Projection(Vector4.Zero, Vector4.Zero, Vector4.Zero, Vector4.Zero)</c>.</value>
|
||||
public static Projection Zero { get { return _zero; } }
|
||||
|
||||
/// <summary>
|
||||
/// The identity projection, with no distortion applied.
|
||||
/// This is used as a replacement for <c>Projection()</c> in GDScript.
|
||||
/// Do not use <c>new Projection()</c> with no arguments in C#, because it sets all values to zero.
|
||||
/// </summary>
|
||||
/// <value>Equivalent to <c>new Projection(new Vector4(1, 0, 0, 0), new Vector4(0, 1, 0, 0), new Vector4(0, 0, 1, 0), new Vector4(0, 0, 0, 1))</c>.</value>
|
||||
public static Projection Identity { get { return _identity; } }
|
||||
|
||||
/// <summary>
|
||||
/// Serves as the hash function for <see cref="Projection"/>.
|
||||
/// </summary>
|
||||
/// <returns>A hash code for this projection.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return y.GetHashCode() ^ x.GetHashCode() ^ z.GetHashCode() ^ w.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts this <see cref="Projection"/> to a string.
|
||||
/// </summary>
|
||||
/// <returns>A string representation of this projection.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{x.x}, {x.y}, {x.z}, {x.w}\n{y.x}, {y.y}, {y.z}, {y.w}\n{z.x}, {z.y}, {z.z}, {z.w}\n{w.x}, {w.y}, {w.z}, {w.w}\n";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts this <see cref="Projection"/> to a string with the given <paramref name="format"/>.
|
||||
/// </summary>
|
||||
/// <returns>A string representation of this projection.</returns>
|
||||
public string ToString(string format)
|
||||
{
|
||||
return $"{x.x.ToString(format)}, {x.y.ToString(format)}, {x.z.ToString(format)}, {x.w.ToString(format)}\n" +
|
||||
$"{y.x.ToString(format)}, {y.y.ToString(format)}, {y.z.ToString(format)}, {y.w.ToString(format)}\n" +
|
||||
$"{z.x.ToString(format)}, {z.y.ToString(format)}, {z.z.ToString(format)}, {z.w.ToString(format)}\n" +
|
||||
$"{w.x.ToString(format)}, {w.y.ToString(format)}, {w.z.ToString(format)}, {w.w.ToString(format)}\n";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns <see langword="true"/> if the projection is exactly equal
|
||||
/// to the given object (<see paramref="obj"/>).
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to compare with.</param>
|
||||
/// <returns>Whether or not the vector and the object are equal.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is Projection)
|
||||
{
|
||||
return Equals((Projection)obj);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns <see langword="true"/> if the projections are exactly equal.
|
||||
/// </summary>
|
||||
/// <param name="other">The other projection.</param>
|
||||
/// <returns>Whether or not the projections are exactly equal.</returns>
|
||||
public bool Equals(Projection other)
|
||||
{
|
||||
return x == other.x && y == other.y && z == other.z && w == other.w;
|
||||
}
|
||||
}
|
||||
}
|
730
modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs
Normal file
730
modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs
Normal file
@ -0,0 +1,730 @@
|
||||
#if REAL_T_IS_DOUBLE
|
||||
using real_t = System.Double;
|
||||
#else
|
||||
using real_t = System.Single;
|
||||
#endif
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Godot
|
||||
{
|
||||
/// <summary>
|
||||
/// 4-element structure that can be used to represent positions in 4D space or any other pair of numeric values.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Vector4 : IEquatable<Vector4>
|
||||
{
|
||||
/// <summary>
|
||||
/// Enumerated index values for the axes.
|
||||
/// Returned by <see cref="MaxAxisIndex"/> and <see cref="MinAxisIndex"/>.
|
||||
/// </summary>
|
||||
public enum Axis
|
||||
{
|
||||
/// <summary>
|
||||
/// The vector's X axis.
|
||||
/// </summary>
|
||||
X = 0,
|
||||
/// <summary>
|
||||
/// The vector's Y axis.
|
||||
/// </summary>
|
||||
Y,
|
||||
/// <summary>
|
||||
/// The vector's Z axis.
|
||||
/// </summary>
|
||||
Z,
|
||||
/// <summary>
|
||||
/// The vector's W axis.
|
||||
/// </summary>
|
||||
W
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The vector's X component. Also accessible by using the index position <c>[0]</c>.
|
||||
/// </summary>
|
||||
public real_t x;
|
||||
|
||||
/// <summary>
|
||||
/// The vector's Y component. Also accessible by using the index position <c>[1]</c>.
|
||||
/// </summary>
|
||||
public real_t y;
|
||||
|
||||
/// <summary>
|
||||
/// The vector's Z component. Also accessible by using the index position <c>[2]</c>.
|
||||
/// </summary>
|
||||
public real_t z;
|
||||
|
||||
/// <summary>
|
||||
/// The vector's W component. Also accessible by using the index position <c>[3]</c>.
|
||||
/// </summary>
|
||||
public real_t w;
|
||||
|
||||
/// <summary>
|
||||
/// Access vector components using their index.
|
||||
/// </summary>
|
||||
/// <exception cref="IndexOutOfRangeException">
|
||||
/// Thrown when the given the <paramref name="index"/> is not 0, 1, 2 or 3.
|
||||
/// </exception>
|
||||
/// <value>
|
||||
/// <c>[0]</c> is equivalent to <see cref="x"/>,
|
||||
/// <c>[1]</c> is equivalent to <see cref="y"/>,
|
||||
/// <c>[2]</c> is equivalent to <see cref="z"/>.
|
||||
/// <c>[3]</c> is equivalent to <see cref="w"/>.
|
||||
/// </value>
|
||||
public real_t this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return x;
|
||||
case 1:
|
||||
return y;
|
||||
case 2:
|
||||
return z;
|
||||
case 3:
|
||||
return w;
|
||||
default:
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
x = value;
|
||||
return;
|
||||
case 1:
|
||||
y = value;
|
||||
return;
|
||||
case 2:
|
||||
z = value;
|
||||
return;
|
||||
case 3:
|
||||
w = value;
|
||||
return;
|
||||
default:
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method for deconstruction into a tuple.
|
||||
/// </summary>
|
||||
public void Deconstruct(out real_t x, out real_t y, out real_t z, out real_t w)
|
||||
{
|
||||
x = this.x;
|
||||
y = this.y;
|
||||
z = this.z;
|
||||
w = this.w;
|
||||
}
|
||||
|
||||
internal void Normalize()
|
||||
{
|
||||
real_t lengthsq = LengthSquared();
|
||||
|
||||
if (lengthsq == 0)
|
||||
{
|
||||
x = y = z = w = 0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
real_t length = Mathf.Sqrt(lengthsq);
|
||||
x /= length;
|
||||
y /= length;
|
||||
z /= length;
|
||||
w /= length;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new vector with all components in absolute values (i.e. positive).
|
||||
/// </summary>
|
||||
/// <returns>A vector with <see cref="Mathf.Abs(real_t)"/> called on each component.</returns>
|
||||
public Vector4 Abs()
|
||||
{
|
||||
return new Vector4(Mathf.Abs(x), Mathf.Abs(y), Mathf.Abs(z), Mathf.Abs(w));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new vector with all components rounded up (towards positive infinity).
|
||||
/// </summary>
|
||||
/// <returns>A vector with <see cref="Mathf.Ceil"/> called on each component.</returns>
|
||||
public Vector4 Ceil()
|
||||
{
|
||||
return new Vector4(Mathf.Ceil(x), Mathf.Ceil(y), Mathf.Ceil(z), Mathf.Ceil(w));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new vector with all components clamped between the
|
||||
/// components of <paramref name="min"/> and <paramref name="max"/> using
|
||||
/// <see cref="Mathf.Clamp(real_t, real_t, real_t)"/>.
|
||||
/// </summary>
|
||||
/// <param name="min">The vector with minimum allowed values.</param>
|
||||
/// <param name="max">The vector with maximum allowed values.</param>
|
||||
/// <returns>The vector with all components clamped.</returns>
|
||||
public Vector4 Clamp(Vector4 min, Vector4 max)
|
||||
{
|
||||
return new Vector4
|
||||
(
|
||||
Mathf.Clamp(x, min.x, max.x),
|
||||
Mathf.Clamp(y, min.y, max.y),
|
||||
Mathf.Clamp(z, min.z, max.z),
|
||||
Mathf.Clamp(w, min.w, max.w)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new vector with all components rounded down (towards negative infinity).
|
||||
/// </summary>
|
||||
/// <returns>A vector with <see cref="Mathf.Floor"/> called on each component.</returns>
|
||||
public Vector4 Floor()
|
||||
{
|
||||
return new Vector4(Mathf.Floor(x), Mathf.Floor(y), Mathf.Floor(z), Mathf.Floor(w));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the dot product of this vector and <paramref name="with"/>.
|
||||
/// </summary>
|
||||
/// <param name="with">The other vector to use.</param>
|
||||
/// <returns>The dot product of the two vectors.</returns>
|
||||
public real_t Dot(Vector4 with)
|
||||
{
|
||||
return (x * with.x) + (y * with.y) + (z * with.z) + (w + with.w);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the inverse of this vector. This is the same as <c>new Vector4(1 / v.x, 1 / v.y, 1 / v.z, 1 / v.w)</c>.
|
||||
/// </summary>
|
||||
/// <returns>The inverse of this vector.</returns>
|
||||
public Vector4 Inverse()
|
||||
{
|
||||
return new Vector4(1 / x, 1 / y, 1 / z, 1 / w);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns <see langword="true"/> if the vector is normalized, and <see langword="false"/> otherwise.
|
||||
/// </summary>
|
||||
/// <returns>A <see langword="bool"/> indicating whether or not the vector is normalized.</returns>
|
||||
public bool IsNormalized()
|
||||
{
|
||||
return Mathf.Abs(LengthSquared() - 1.0f) < Mathf.Epsilon;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the length (magnitude) of this vector.
|
||||
/// </summary>
|
||||
/// <seealso cref="LengthSquared"/>
|
||||
/// <returns>The length of this vector.</returns>
|
||||
public real_t Length()
|
||||
{
|
||||
real_t x2 = x * x;
|
||||
real_t y2 = y * y;
|
||||
real_t z2 = z * z;
|
||||
real_t w2 = w * w;
|
||||
|
||||
return Mathf.Sqrt(x2 + y2 + z2 + w2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the squared length (squared magnitude) of this vector.
|
||||
/// This method runs faster than <see cref="Length"/>, so prefer it if
|
||||
/// you need to compare vectors or need the squared length for some formula.
|
||||
/// </summary>
|
||||
/// <returns>The squared length of this vector.</returns>
|
||||
public real_t LengthSquared()
|
||||
{
|
||||
real_t x2 = x * x;
|
||||
real_t y2 = y * y;
|
||||
real_t z2 = z * z;
|
||||
real_t w2 = w * w;
|
||||
|
||||
return x2 + y2 + z2 + w2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the result of the linear interpolation between
|
||||
/// this vector and <paramref name="to"/> by amount <paramref name="weight"/>.
|
||||
/// </summary>
|
||||
/// <param name="to">The destination vector for interpolation.</param>
|
||||
/// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
|
||||
/// <returns>The resulting vector of the interpolation.</returns>
|
||||
public Vector4 Lerp(Vector4 to, real_t weight)
|
||||
{
|
||||
return new Vector4
|
||||
(
|
||||
Mathf.Lerp(x, to.x, weight),
|
||||
Mathf.Lerp(y, to.y, weight),
|
||||
Mathf.Lerp(z, to.z, weight),
|
||||
Mathf.Lerp(w, to.w, weight)
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the axis of the vector's highest value. See <see cref="Axis"/>.
|
||||
/// If all components are equal, this method returns <see cref="Axis.X"/>.
|
||||
/// </summary>
|
||||
/// <returns>The index of the highest axis.</returns>
|
||||
public Axis MaxAxisIndex()
|
||||
{
|
||||
int max_index = 0;
|
||||
real_t max_value = x;
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
if (this[i] > max_value)
|
||||
{
|
||||
max_index = i;
|
||||
max_value = this[i];
|
||||
}
|
||||
}
|
||||
return (Axis)max_index;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the axis of the vector's lowest value. See <see cref="Axis"/>.
|
||||
/// If all components are equal, this method returns <see cref="Axis.W"/>.
|
||||
/// </summary>
|
||||
/// <returns>The index of the lowest axis.</returns>
|
||||
public Axis MinAxisIndex()
|
||||
{
|
||||
int min_index = 0;
|
||||
real_t min_value = x;
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
if (this[i] <= min_value)
|
||||
{
|
||||
min_index = i;
|
||||
min_value = this[i];
|
||||
}
|
||||
}
|
||||
return (Axis)min_index;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the vector scaled to unit length. Equivalent to <c>v / v.Length()</c>.
|
||||
/// </summary>
|
||||
/// <returns>A normalized version of the vector.</returns>
|
||||
public Vector4 Normalized()
|
||||
{
|
||||
Vector4 v = this;
|
||||
v.Normalize();
|
||||
return v;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns this vector with all components rounded to the nearest integer,
|
||||
/// with halfway cases rounded towards the nearest multiple of two.
|
||||
/// </summary>
|
||||
/// <returns>The rounded vector.</returns>
|
||||
public Vector4 Round()
|
||||
{
|
||||
return new Vector4(Mathf.Round(x), Mathf.Round(y), Mathf.Round(z), Mathf.Round(w));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a vector with each component set to one or negative one, depending
|
||||
/// on the signs of this vector's components, or zero if the component is zero,
|
||||
/// by calling <see cref="Mathf.Sign(real_t)"/> on each component.
|
||||
/// </summary>
|
||||
/// <returns>A vector with all components as either <c>1</c>, <c>-1</c>, or <c>0</c>.</returns>
|
||||
public Vector4 Sign()
|
||||
{
|
||||
Vector4 v;
|
||||
v.x = Mathf.Sign(x);
|
||||
v.y = Mathf.Sign(y);
|
||||
v.z = Mathf.Sign(z);
|
||||
v.w = Mathf.Sign(w);
|
||||
return v;
|
||||
}
|
||||
|
||||
// Constants
|
||||
private static readonly Vector4 _zero = new Vector4(0, 0, 0, 0);
|
||||
private static readonly Vector4 _one = new Vector4(1, 1, 1, 1);
|
||||
private static readonly Vector4 _inf = new Vector4(Mathf.Inf, Mathf.Inf, Mathf.Inf, Mathf.Inf);
|
||||
|
||||
/// <summary>
|
||||
/// Zero vector, a vector with all components set to <c>0</c>.
|
||||
/// </summary>
|
||||
/// <value>Equivalent to <c>new Vector4(0, 0, 0, 0)</c>.</value>
|
||||
public static Vector4 Zero { get { return _zero; } }
|
||||
/// <summary>
|
||||
/// One vector, a vector with all components set to <c>1</c>.
|
||||
/// </summary>
|
||||
/// <value>Equivalent to <c>new Vector4(1, 1, 1, 1)</c>.</value>
|
||||
public static Vector4 One { get { return _one; } }
|
||||
/// <summary>
|
||||
/// Infinity vector, a vector with all components set to <see cref="Mathf.Inf"/>.
|
||||
/// </summary>
|
||||
/// <value>Equivalent to <c>new Vector4(Mathf.Inf, Mathf.Inf, Mathf.Inf, Mathf.Inf)</c>.</value>
|
||||
public static Vector4 Inf { get { return _inf; } }
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="Vector4"/> with the given components.
|
||||
/// </summary>
|
||||
/// <param name="x">The vector's X component.</param>
|
||||
/// <param name="y">The vector's Y component.</param>
|
||||
/// <param name="z">The vector's Z component.</param>
|
||||
/// <param name="w">The vector's W component.</param>
|
||||
public Vector4(real_t x, real_t y, real_t z, real_t w)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.w = w;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="Vector4"/> from an existing <see cref="Vector4"/>.
|
||||
/// </summary>
|
||||
/// <param name="v">The existing <see cref="Vector4"/>.</param>
|
||||
public Vector4(Vector4 v)
|
||||
{
|
||||
x = v.x;
|
||||
y = v.y;
|
||||
z = v.z;
|
||||
w = v.w;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds each component of the <see cref="Vector4"/>
|
||||
/// with the components of the given <see cref="Vector4"/>.
|
||||
/// </summary>
|
||||
/// <param name="left">The left vector.</param>
|
||||
/// <param name="right">The right vector.</param>
|
||||
/// <returns>The added vector.</returns>
|
||||
public static Vector4 operator +(Vector4 left, Vector4 right)
|
||||
{
|
||||
left.x += right.x;
|
||||
left.y += right.y;
|
||||
left.z += right.z;
|
||||
left.w += right.w;
|
||||
return left;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtracts each component of the <see cref="Vector4"/>
|
||||
/// by the components of the given <see cref="Vector4"/>.
|
||||
/// </summary>
|
||||
/// <param name="left">The left vector.</param>
|
||||
/// <param name="right">The right vector.</param>
|
||||
/// <returns>The subtracted vector.</returns>
|
||||
public static Vector4 operator -(Vector4 left, Vector4 right)
|
||||
{
|
||||
left.x -= right.x;
|
||||
left.y -= right.y;
|
||||
left.z -= right.z;
|
||||
left.w -= right.w;
|
||||
return left;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the negative value of the <see cref="Vector4"/>.
|
||||
/// This is the same as writing <c>new Vector4(-v.x, -v.y, -v.z, -v.w)</c>.
|
||||
/// This operation flips the direction of the vector while
|
||||
/// keeping the same magnitude.
|
||||
/// With floats, the number zero can be either positive or negative.
|
||||
/// </summary>
|
||||
/// <param name="vec">The vector to negate/flip.</param>
|
||||
/// <returns>The negated/flipped vector.</returns>
|
||||
public static Vector4 operator -(Vector4 vec)
|
||||
{
|
||||
vec.x = -vec.x;
|
||||
vec.y = -vec.y;
|
||||
vec.z = -vec.z;
|
||||
vec.w = -vec.w;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Multiplies each component of the <see cref="Vector4"/>
|
||||
/// by the given <see cref="real_t"/>.
|
||||
/// </summary>
|
||||
/// <param name="vec">The vector to multiply.</param>
|
||||
/// <param name="scale">The scale to multiply by.</param>
|
||||
/// <returns>The multiplied vector.</returns>
|
||||
public static Vector4 operator *(Vector4 vec, real_t scale)
|
||||
{
|
||||
vec.x *= scale;
|
||||
vec.y *= scale;
|
||||
vec.z *= scale;
|
||||
vec.w *= scale;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Multiplies each component of the <see cref="Vector4"/>
|
||||
/// by the given <see cref="real_t"/>.
|
||||
/// </summary>
|
||||
/// <param name="scale">The scale to multiply by.</param>
|
||||
/// <param name="vec">The vector to multiply.</param>
|
||||
/// <returns>The multiplied vector.</returns>
|
||||
public static Vector4 operator *(real_t scale, Vector4 vec)
|
||||
{
|
||||
vec.x *= scale;
|
||||
vec.y *= scale;
|
||||
vec.z *= scale;
|
||||
vec.w *= scale;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Multiplies each component of the <see cref="Vector4"/>
|
||||
/// by the components of the given <see cref="Vector4"/>.
|
||||
/// </summary>
|
||||
/// <param name="left">The left vector.</param>
|
||||
/// <param name="right">The right vector.</param>
|
||||
/// <returns>The multiplied vector.</returns>
|
||||
public static Vector4 operator *(Vector4 left, Vector4 right)
|
||||
{
|
||||
left.x *= right.x;
|
||||
left.y *= right.y;
|
||||
left.z *= right.z;
|
||||
left.w *= right.w;
|
||||
return left;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Divides each component of the <see cref="Vector4"/>
|
||||
/// by the given <see cref="real_t"/>.
|
||||
/// </summary>
|
||||
/// <param name="vec">The dividend vector.</param>
|
||||
/// <param name="divisor">The divisor value.</param>
|
||||
/// <returns>The divided vector.</returns>
|
||||
public static Vector4 operator /(Vector4 vec, real_t divisor)
|
||||
{
|
||||
vec.x /= divisor;
|
||||
vec.y /= divisor;
|
||||
vec.z /= divisor;
|
||||
vec.w /= divisor;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Divides each component of the <see cref="Vector4"/>
|
||||
/// by the components of the given <see cref="Vector4"/>.
|
||||
/// </summary>
|
||||
/// <param name="vec">The dividend vector.</param>
|
||||
/// <param name="divisorv">The divisor vector.</param>
|
||||
/// <returns>The divided vector.</returns>
|
||||
public static Vector4 operator /(Vector4 vec, Vector4 divisorv)
|
||||
{
|
||||
vec.x /= divisorv.x;
|
||||
vec.y /= divisorv.y;
|
||||
vec.z /= divisorv.z;
|
||||
vec.w /= divisorv.w;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns <see langword="true"/> if the vectors are exactly equal.
|
||||
/// Note: Due to floating-point precision errors, consider using
|
||||
/// <see cref="IsEqualApprox"/> instead, which is more reliable.
|
||||
/// </summary>
|
||||
/// <param name="left">The left vector.</param>
|
||||
/// <param name="right">The right vector.</param>
|
||||
/// <returns>Whether or not the vectors are exactly equal.</returns>
|
||||
public static bool operator ==(Vector4 left, Vector4 right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns <see langword="true"/> if the vectors are not equal.
|
||||
/// Note: Due to floating-point precision errors, consider using
|
||||
/// <see cref="IsEqualApprox"/> instead, which is more reliable.
|
||||
/// </summary>
|
||||
/// <param name="left">The left vector.</param>
|
||||
/// <param name="right">The right vector.</param>
|
||||
/// <returns>Whether or not the vectors are not equal.</returns>
|
||||
public static bool operator !=(Vector4 left, Vector4 right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two <see cref="Vector4"/> vectors by first checking if
|
||||
/// the X value of the <paramref name="left"/> vector is less than
|
||||
/// the X value of the <paramref name="right"/> vector.
|
||||
/// If the X values are exactly equal, then it repeats this check
|
||||
/// with the Y, Z and finally W values of the two vectors.
|
||||
/// This operator is useful for sorting vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The left vector.</param>
|
||||
/// <param name="right">The right vector.</param>
|
||||
/// <returns>Whether or not the left is less than the right.</returns>
|
||||
public static bool operator <(Vector4 left, Vector4 right)
|
||||
{
|
||||
if (left.x == right.x)
|
||||
{
|
||||
if (left.y == right.y)
|
||||
{
|
||||
if (left.z == right.z)
|
||||
{
|
||||
return left.w < right.w;
|
||||
}
|
||||
return left.z < right.z;
|
||||
}
|
||||
return left.y < right.y;
|
||||
}
|
||||
return left.x < right.x;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two <see cref="Vector4"/> vectors by first checking if
|
||||
/// the X value of the <paramref name="left"/> vector is greater than
|
||||
/// the X value of the <paramref name="right"/> vector.
|
||||
/// If the X values are exactly equal, then it repeats this check
|
||||
/// with the Y, Z and finally W values of the two vectors.
|
||||
/// This operator is useful for sorting vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The left vector.</param>
|
||||
/// <param name="right">The right vector.</param>
|
||||
/// <returns>Whether or not the left is greater than the right.</returns>
|
||||
public static bool operator >(Vector4 left, Vector4 right)
|
||||
{
|
||||
if (left.x == right.x)
|
||||
{
|
||||
if (left.y == right.y)
|
||||
{
|
||||
if (left.z == right.z)
|
||||
{
|
||||
return left.w > right.w;
|
||||
}
|
||||
return left.z > right.z;
|
||||
}
|
||||
return left.y > right.y;
|
||||
}
|
||||
return left.x > right.x;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two <see cref="Vector4"/> vectors by first checking if
|
||||
/// the X value of the <paramref name="left"/> vector is less than
|
||||
/// or equal to the X value of the <paramref name="right"/> vector.
|
||||
/// If the X values are exactly equal, then it repeats this check
|
||||
/// with the Y, Z and finally W values of the two vectors.
|
||||
/// This operator is useful for sorting vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The left vector.</param>
|
||||
/// <param name="right">The right vector.</param>
|
||||
/// <returns>Whether or not the left is less than or equal to the right.</returns>
|
||||
public static bool operator <=(Vector4 left, Vector4 right)
|
||||
{
|
||||
if (left.x == right.x)
|
||||
{
|
||||
if (left.y == right.y)
|
||||
{
|
||||
if (left.z == right.z)
|
||||
{
|
||||
return left.w <= right.w;
|
||||
}
|
||||
return left.z < right.z;
|
||||
}
|
||||
return left.y < right.y;
|
||||
}
|
||||
return left.x < right.x;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two <see cref="Vector4"/> vectors by first checking if
|
||||
/// the X value of the <paramref name="left"/> vector is greater than
|
||||
/// or equal to the X value of the <paramref name="right"/> vector.
|
||||
/// If the X values are exactly equal, then it repeats this check
|
||||
/// with the Y, Z and finally W values of the two vectors.
|
||||
/// This operator is useful for sorting vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The left vector.</param>
|
||||
/// <param name="right">The right vector.</param>
|
||||
/// <returns>Whether or not the left is greater than or equal to the right.</returns>
|
||||
public static bool operator >=(Vector4 left, Vector4 right)
|
||||
{
|
||||
if (left.x == right.x)
|
||||
{
|
||||
if (left.y == right.y)
|
||||
{
|
||||
if (left.z == right.z)
|
||||
{
|
||||
return left.w >= right.w;
|
||||
}
|
||||
return left.z > right.z;
|
||||
}
|
||||
return left.y > right.y;
|
||||
}
|
||||
return left.x > right.x;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns <see langword="true"/> if the vector is exactly equal
|
||||
/// to the given object (<see paramref="obj"/>).
|
||||
/// Note: Due to floating-point precision errors, consider using
|
||||
/// <see cref="IsEqualApprox"/> instead, which is more reliable.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to compare with.</param>
|
||||
/// <returns>Whether or not the vector and the object are equal.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is Vector4)
|
||||
{
|
||||
return Equals((Vector4)obj);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns <see langword="true"/> if the vectors are exactly equal.
|
||||
/// Note: Due to floating-point precision errors, consider using
|
||||
/// <see cref="IsEqualApprox"/> instead, which is more reliable.
|
||||
/// </summary>
|
||||
/// <param name="other">The other vector.</param>
|
||||
/// <returns>Whether or not the vectors are exactly equal.</returns>
|
||||
public bool Equals(Vector4 other)
|
||||
{
|
||||
return x == other.x && y == other.y && z == other.z && w == other.w;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns <see langword="true"/> if this vector and <paramref name="other"/> are approximately equal,
|
||||
/// by running <see cref="Mathf.IsEqualApprox(real_t, real_t)"/> on each component.
|
||||
/// </summary>
|
||||
/// <param name="other">The other vector to compare.</param>
|
||||
/// <returns>Whether or not the vectors are approximately equal.</returns>
|
||||
public bool IsEqualApprox(Vector4 other)
|
||||
{
|
||||
return Mathf.IsEqualApprox(x, other.x) && Mathf.IsEqualApprox(y, other.y) && Mathf.IsEqualApprox(z, other.z) && Mathf.IsEqualApprox(w, other.w);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serves as the hash function for <see cref="Vector4"/>.
|
||||
/// </summary>
|
||||
/// <returns>A hash code for this vector.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return y.GetHashCode() ^ x.GetHashCode() ^ z.GetHashCode() ^ w.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts this <see cref="Vector4"/> to a string.
|
||||
/// </summary>
|
||||
/// <returns>A string representation of this vector.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return $"({x}, {y}, {z}, {w})";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts this <see cref="Vector4"/> to a string with the given <paramref name="format"/>.
|
||||
/// </summary>
|
||||
/// <returns>A string representation of this vector.</returns>
|
||||
public string ToString(string format)
|
||||
{
|
||||
return $"({x.ToString(format)}, {y.ToString(format)}, {z.ToString(format)}, {w.ToString(format)})";
|
||||
}
|
||||
}
|
||||
}
|
702
modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4i.cs
Normal file
702
modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4i.cs
Normal file
@ -0,0 +1,702 @@
|
||||
#if REAL_T_IS_DOUBLE
|
||||
using real_t = System.Double;
|
||||
#else
|
||||
using real_t = System.Single;
|
||||
#endif
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Godot
|
||||
{
|
||||
/// <summary>
|
||||
/// 4-element structure that can be used to represent 4D grid coordinates or sets of integers.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Vector4i : IEquatable<Vector4i>
|
||||
{
|
||||
/// <summary>
|
||||
/// Enumerated index values for the axes.
|
||||
/// Returned by <see cref="MaxAxisIndex"/> and <see cref="MinAxisIndex"/>.
|
||||
/// </summary>
|
||||
public enum Axis
|
||||
{
|
||||
/// <summary>
|
||||
/// The vector's X axis.
|
||||
/// </summary>
|
||||
X = 0,
|
||||
/// <summary>
|
||||
/// The vector's Y axis.
|
||||
/// </summary>
|
||||
Y,
|
||||
/// <summary>
|
||||
/// The vector's Z axis.
|
||||
/// </summary>
|
||||
Z,
|
||||
/// <summary>
|
||||
/// The vector's W axis.
|
||||
/// </summary>
|
||||
W
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The vector's X component. Also accessible by using the index position <c>[0]</c>.
|
||||
/// </summary>
|
||||
public int x;
|
||||
|
||||
/// <summary>
|
||||
/// The vector's Y component. Also accessible by using the index position <c>[1]</c>.
|
||||
/// </summary>
|
||||
public int y;
|
||||
|
||||
/// <summary>
|
||||
/// The vector's Z component. Also accessible by using the index position <c>[2]</c>.
|
||||
/// </summary>
|
||||
public int z;
|
||||
|
||||
/// <summary>
|
||||
/// The vector's W component. Also accessible by using the index position <c>[3]</c>.
|
||||
/// </summary>
|
||||
public int w;
|
||||
|
||||
/// <summary>
|
||||
/// Access vector components using their <paramref name="index"/>.
|
||||
/// </summary>
|
||||
/// <exception cref="IndexOutOfRangeException">
|
||||
/// Thrown when the given the <paramref name="index"/> is not 0, 1, 2 or 3.
|
||||
/// </exception>
|
||||
/// <value>
|
||||
/// <c>[0]</c> is equivalent to <see cref="x"/>,
|
||||
/// <c>[1]</c> is equivalent to <see cref="y"/>,
|
||||
/// <c>[2]</c> is equivalent to <see cref="z"/>.
|
||||
/// <c>[3]</c> is equivalent to <see cref="w"/>.
|
||||
/// </value>
|
||||
public int this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return x;
|
||||
case 1:
|
||||
return y;
|
||||
case 2:
|
||||
return z;
|
||||
case 3:
|
||||
return w;
|
||||
default:
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
x = value;
|
||||
return;
|
||||
case 1:
|
||||
y = value;
|
||||
return;
|
||||
case 2:
|
||||
z = value;
|
||||
return;
|
||||
case 3:
|
||||
w = value;
|
||||
return;
|
||||
default:
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method for deconstruction into a tuple.
|
||||
/// </summary>
|
||||
public void Deconstruct(out int x, out int y, out int z, out int w)
|
||||
{
|
||||
x = this.x;
|
||||
y = this.y;
|
||||
z = this.z;
|
||||
w = this.w;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new vector with all components in absolute values (i.e. positive).
|
||||
/// </summary>
|
||||
/// <returns>A vector with <see cref="Mathf.Abs(int)"/> called on each component.</returns>
|
||||
public Vector4i Abs()
|
||||
{
|
||||
return new Vector4i(Mathf.Abs(x), Mathf.Abs(y), Mathf.Abs(z), Mathf.Abs(w));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new vector with all components clamped between the
|
||||
/// components of <paramref name="min"/> and <paramref name="max"/> using
|
||||
/// <see cref="Mathf.Clamp(int, int, int)"/>.
|
||||
/// </summary>
|
||||
/// <param name="min">The vector with minimum allowed values.</param>
|
||||
/// <param name="max">The vector with maximum allowed values.</param>
|
||||
/// <returns>The vector with all components clamped.</returns>
|
||||
public Vector4i Clamp(Vector4i min, Vector4i max)
|
||||
{
|
||||
return new Vector4i
|
||||
(
|
||||
Mathf.Clamp(x, min.x, max.x),
|
||||
Mathf.Clamp(y, min.y, max.y),
|
||||
Mathf.Clamp(z, min.z, max.z),
|
||||
Mathf.Clamp(w, min.w, max.w)
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the length (magnitude) of this vector.
|
||||
/// </summary>
|
||||
/// <seealso cref="LengthSquared"/>
|
||||
/// <returns>The length of this vector.</returns>
|
||||
public real_t Length()
|
||||
{
|
||||
int x2 = x * x;
|
||||
int y2 = y * y;
|
||||
int z2 = z * z;
|
||||
int w2 = w * w;
|
||||
|
||||
return Mathf.Sqrt(x2 + y2 + z2 + w2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the squared length (squared magnitude) of this vector.
|
||||
/// This method runs faster than <see cref="Length"/>, so prefer it if
|
||||
/// you need to compare vectors or need the squared length for some formula.
|
||||
/// </summary>
|
||||
/// <returns>The squared length of this vector.</returns>
|
||||
public int LengthSquared()
|
||||
{
|
||||
int x2 = x * x;
|
||||
int y2 = y * y;
|
||||
int z2 = z * z;
|
||||
int w2 = w * w;
|
||||
|
||||
return x2 + y2 + z2 + w2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the axis of the vector's highest value. See <see cref="Axis"/>.
|
||||
/// If all components are equal, this method returns <see cref="Axis.X"/>.
|
||||
/// </summary>
|
||||
/// <returns>The index of the highest axis.</returns>
|
||||
public Axis MaxAxisIndex()
|
||||
{
|
||||
int max_index = 0;
|
||||
int max_value = x;
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
if (this[i] > max_value)
|
||||
{
|
||||
max_index = i;
|
||||
max_value = this[i];
|
||||
}
|
||||
}
|
||||
return (Axis)max_index;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the axis of the vector's lowest value. See <see cref="Axis"/>.
|
||||
/// If all components are equal, this method returns <see cref="Axis.W"/>.
|
||||
/// </summary>
|
||||
/// <returns>The index of the lowest axis.</returns>
|
||||
public Axis MinAxisIndex()
|
||||
{
|
||||
int min_index = 0;
|
||||
int min_value = x;
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
if (this[i] <= min_value)
|
||||
{
|
||||
min_index = i;
|
||||
min_value = this[i];
|
||||
}
|
||||
}
|
||||
return (Axis)min_index;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a vector with each component set to one or negative one, depending
|
||||
/// on the signs of this vector's components, or zero if the component is zero,
|
||||
/// by calling <see cref="Mathf.Sign(int)"/> on each component.
|
||||
/// </summary>
|
||||
/// <returns>A vector with all components as either <c>1</c>, <c>-1</c>, or <c>0</c>.</returns>
|
||||
public Vector4i Sign()
|
||||
{
|
||||
return new Vector4i(Mathf.Sign(x), Mathf.Sign(y), Mathf.Sign(z), Mathf.Sign(w));
|
||||
}
|
||||
|
||||
// Constants
|
||||
private static readonly Vector4i _zero = new Vector4i(0, 0, 0, 0);
|
||||
private static readonly Vector4i _one = new Vector4i(1, 1, 1, 1);
|
||||
|
||||
/// <summary>
|
||||
/// Zero vector, a vector with all components set to <c>0</c>.
|
||||
/// </summary>
|
||||
/// <value>Equivalent to <c>new Vector4i(0, 0, 0, 0)</c>.</value>
|
||||
public static Vector4i Zero { get { return _zero; } }
|
||||
/// <summary>
|
||||
/// One vector, a vector with all components set to <c>1</c>.
|
||||
/// </summary>
|
||||
/// <value>Equivalent to <c>new Vector4i(1, 1, 1, 1)</c>.</value>
|
||||
public static Vector4i One { get { return _one; } }
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="Vector4i"/> with the given components.
|
||||
/// </summary>
|
||||
/// <param name="x">The vector's X component.</param>
|
||||
/// <param name="y">The vector's Y component.</param>
|
||||
/// <param name="z">The vector's Z component.</param>
|
||||
/// <param name="w">The vector's W component.</param>
|
||||
public Vector4i(int x, int y, int z, int w)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.w = w;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="Vector4i"/> from an existing <see cref="Vector4i"/>.
|
||||
/// </summary>
|
||||
/// <param name="vi">The existing <see cref="Vector4i"/>.</param>
|
||||
public Vector4i(Vector4i vi)
|
||||
{
|
||||
this.x = vi.x;
|
||||
this.y = vi.y;
|
||||
this.z = vi.z;
|
||||
this.w = vi.w;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="Vector4i"/> from an existing <see cref="Vector4"/>
|
||||
/// by rounding the components via <see cref="Mathf.RoundToInt(real_t)"/>.
|
||||
/// </summary>
|
||||
/// <param name="v">The <see cref="Vector4"/> to convert.</param>
|
||||
public Vector4i(Vector4 v)
|
||||
{
|
||||
this.x = Mathf.RoundToInt(v.x);
|
||||
this.y = Mathf.RoundToInt(v.y);
|
||||
this.z = Mathf.RoundToInt(v.z);
|
||||
this.w = Mathf.RoundToInt(v.w);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds each component of the <see cref="Vector4i"/>
|
||||
/// with the components of the given <see cref="Vector4i"/>.
|
||||
/// </summary>
|
||||
/// <param name="left">The left vector.</param>
|
||||
/// <param name="right">The right vector.</param>
|
||||
/// <returns>The added vector.</returns>
|
||||
public static Vector4i operator +(Vector4i left, Vector4i right)
|
||||
{
|
||||
left.x += right.x;
|
||||
left.y += right.y;
|
||||
left.z += right.z;
|
||||
left.w += right.w;
|
||||
return left;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtracts each component of the <see cref="Vector4i"/>
|
||||
/// by the components of the given <see cref="Vector4i"/>.
|
||||
/// </summary>
|
||||
/// <param name="left">The left vector.</param>
|
||||
/// <param name="right">The right vector.</param>
|
||||
/// <returns>The subtracted vector.</returns>
|
||||
public static Vector4i operator -(Vector4i left, Vector4i right)
|
||||
{
|
||||
left.x -= right.x;
|
||||
left.y -= right.y;
|
||||
left.z -= right.z;
|
||||
left.w -= right.w;
|
||||
return left;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the negative value of the <see cref="Vector4i"/>.
|
||||
/// This is the same as writing <c>new Vector4i(-v.x, -v.y, -v.z, -v.w)</c>.
|
||||
/// This operation flips the direction of the vector while
|
||||
/// keeping the same magnitude.
|
||||
/// </summary>
|
||||
/// <param name="vec">The vector to negate/flip.</param>
|
||||
/// <returns>The negated/flipped vector.</returns>
|
||||
public static Vector4i operator -(Vector4i vec)
|
||||
{
|
||||
vec.x = -vec.x;
|
||||
vec.y = -vec.y;
|
||||
vec.z = -vec.z;
|
||||
vec.w = -vec.w;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Multiplies each component of the <see cref="Vector4i"/>
|
||||
/// by the given <see langword="int"/>.
|
||||
/// </summary>
|
||||
/// <param name="vec">The vector to multiply.</param>
|
||||
/// <param name="scale">The scale to multiply by.</param>
|
||||
/// <returns>The multiplied vector.</returns>
|
||||
public static Vector4i operator *(Vector4i vec, int scale)
|
||||
{
|
||||
vec.x *= scale;
|
||||
vec.y *= scale;
|
||||
vec.z *= scale;
|
||||
vec.w *= scale;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Multiplies each component of the <see cref="Vector4i"/>
|
||||
/// by the given <see langword="int"/>.
|
||||
/// </summary>
|
||||
/// <param name="scale">The scale to multiply by.</param>
|
||||
/// <param name="vec">The vector to multiply.</param>
|
||||
/// <returns>The multiplied vector.</returns>
|
||||
public static Vector4i operator *(int scale, Vector4i vec)
|
||||
{
|
||||
vec.x *= scale;
|
||||
vec.y *= scale;
|
||||
vec.z *= scale;
|
||||
vec.w *= scale;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Multiplies each component of the <see cref="Vector4i"/>
|
||||
/// by the components of the given <see cref="Vector4i"/>.
|
||||
/// </summary>
|
||||
/// <param name="left">The left vector.</param>
|
||||
/// <param name="right">The right vector.</param>
|
||||
/// <returns>The multiplied vector.</returns>
|
||||
public static Vector4i operator *(Vector4i left, Vector4i right)
|
||||
{
|
||||
left.x *= right.x;
|
||||
left.y *= right.y;
|
||||
left.z *= right.z;
|
||||
left.w *= right.w;
|
||||
return left;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Divides each component of the <see cref="Vector4i"/>
|
||||
/// by the given <see langword="int"/>.
|
||||
/// </summary>
|
||||
/// <param name="vec">The dividend vector.</param>
|
||||
/// <param name="divisor">The divisor value.</param>
|
||||
/// <returns>The divided vector.</returns>
|
||||
public static Vector4i operator /(Vector4i vec, int divisor)
|
||||
{
|
||||
vec.x /= divisor;
|
||||
vec.y /= divisor;
|
||||
vec.z /= divisor;
|
||||
vec.w /= divisor;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Divides each component of the <see cref="Vector4i"/>
|
||||
/// by the components of the given <see cref="Vector4i"/>.
|
||||
/// </summary>
|
||||
/// <param name="vec">The dividend vector.</param>
|
||||
/// <param name="divisorv">The divisor vector.</param>
|
||||
/// <returns>The divided vector.</returns>
|
||||
public static Vector4i operator /(Vector4i vec, Vector4i divisorv)
|
||||
{
|
||||
vec.x /= divisorv.x;
|
||||
vec.y /= divisorv.y;
|
||||
vec.z /= divisorv.z;
|
||||
vec.w /= divisorv.w;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the remainder of each component of the <see cref="Vector4i"/>
|
||||
/// with the components of the given <see langword="int"/>.
|
||||
/// This operation uses truncated division, which is often not desired
|
||||
/// as it does not work well with negative numbers.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// GD.Print(new Vecto43i(10, -20, 30, -40) % 7); // Prints "(3, -6, 2, -5)"
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// <param name="vec">The dividend vector.</param>
|
||||
/// <param name="divisor">The divisor value.</param>
|
||||
/// <returns>The remainder vector.</returns>
|
||||
public static Vector4i operator %(Vector4i vec, int divisor)
|
||||
{
|
||||
vec.x %= divisor;
|
||||
vec.y %= divisor;
|
||||
vec.z %= divisor;
|
||||
vec.w %= divisor;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the remainder of each component of the <see cref="Vector4i"/>
|
||||
/// with the components of the given <see cref="Vector4i"/>.
|
||||
/// This operation uses truncated division, which is often not desired
|
||||
/// as it does not work well with negative numbers.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// GD.Print(new Vector4i(10, -20, 30, -40) % new Vector4i(6, 7, 8, 9)); // Prints "(4, -6, 6, -4)"
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// <param name="vec">The dividend vector.</param>
|
||||
/// <param name="divisorv">The divisor vector.</param>
|
||||
/// <returns>The remainder vector.</returns>
|
||||
public static Vector4i operator %(Vector4i vec, Vector4i divisorv)
|
||||
{
|
||||
vec.x %= divisorv.x;
|
||||
vec.y %= divisorv.y;
|
||||
vec.z %= divisorv.z;
|
||||
vec.w %= divisorv.w;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a bitwise AND operation with this <see cref="Vector4i"/>
|
||||
/// and the given <see langword="int"/>.
|
||||
/// </summary>
|
||||
/// <param name="vec">The vector to AND with.</param>
|
||||
/// <param name="and">The integer to AND with.</param>
|
||||
/// <returns>The result of the bitwise AND.</returns>
|
||||
public static Vector4i operator &(Vector4i vec, int and)
|
||||
{
|
||||
vec.x &= and;
|
||||
vec.y &= and;
|
||||
vec.z &= and;
|
||||
vec.w &= and;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a bitwise AND operation with this <see cref="Vector4i"/>
|
||||
/// and the given <see cref="Vector4i"/>.
|
||||
/// </summary>
|
||||
/// <param name="vec">The left vector to AND with.</param>
|
||||
/// <param name="andv">The right vector to AND with.</param>
|
||||
/// <returns>The result of the bitwise AND.</returns>
|
||||
public static Vector4i operator &(Vector4i vec, Vector4i andv)
|
||||
{
|
||||
vec.x &= andv.x;
|
||||
vec.y &= andv.y;
|
||||
vec.z &= andv.z;
|
||||
vec.w &= andv.w;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns <see langword="true"/> if the vectors are equal.
|
||||
/// </summary>
|
||||
/// <param name="left">The left vector.</param>
|
||||
/// <param name="right">The right vector.</param>
|
||||
/// <returns>Whether or not the vectors are equal.</returns>
|
||||
public static bool operator ==(Vector4i left, Vector4i right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns <see langword="true"/> if the vectors are not equal.
|
||||
/// </summary>
|
||||
/// <param name="left">The left vector.</param>
|
||||
/// <param name="right">The right vector.</param>
|
||||
/// <returns>Whether or not the vectors are not equal.</returns>
|
||||
public static bool operator !=(Vector4i left, Vector4i right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two <see cref="Vector4i"/> vectors by first checking if
|
||||
/// the X value of the <paramref name="left"/> vector is less than
|
||||
/// the X value of the <paramref name="right"/> vector.
|
||||
/// If the X values are exactly equal, then it repeats this check
|
||||
/// with the Y, Z and finally W values of the two vectors.
|
||||
/// This operator is useful for sorting vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The left vector.</param>
|
||||
/// <param name="right">The right vector.</param>
|
||||
/// <returns>Whether or not the left is less than the right.</returns>
|
||||
public static bool operator <(Vector4i left, Vector4i right)
|
||||
{
|
||||
if (left.x == right.x)
|
||||
{
|
||||
if (left.y == right.y)
|
||||
{
|
||||
if (left.z == right.z)
|
||||
{
|
||||
return left.w < right.w;
|
||||
}
|
||||
return left.z < right.z;
|
||||
}
|
||||
return left.y < right.y;
|
||||
}
|
||||
return left.x < right.x;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two <see cref="Vector4i"/> vectors by first checking if
|
||||
/// the X value of the <paramref name="left"/> vector is greater than
|
||||
/// the X value of the <paramref name="right"/> vector.
|
||||
/// If the X values are exactly equal, then it repeats this check
|
||||
/// with the Y, Z and finally W values of the two vectors.
|
||||
/// This operator is useful for sorting vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The left vector.</param>
|
||||
/// <param name="right">The right vector.</param>
|
||||
/// <returns>Whether or not the left is greater than the right.</returns>
|
||||
public static bool operator >(Vector4i left, Vector4i right)
|
||||
{
|
||||
if (left.x == right.x)
|
||||
{
|
||||
if (left.y == right.y)
|
||||
{
|
||||
if (left.z == right.z)
|
||||
{
|
||||
return left.w > right.w;
|
||||
}
|
||||
return left.z > right.z;
|
||||
}
|
||||
return left.y > right.y;
|
||||
}
|
||||
return left.x > right.x;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two <see cref="Vector4i"/> vectors by first checking if
|
||||
/// the X value of the <paramref name="left"/> vector is less than
|
||||
/// or equal to the X value of the <paramref name="right"/> vector.
|
||||
/// If the X values are exactly equal, then it repeats this check
|
||||
/// with the Y, Z and finally W values of the two vectors.
|
||||
/// This operator is useful for sorting vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The left vector.</param>
|
||||
/// <param name="right">The right vector.</param>
|
||||
/// <returns>Whether or not the left is less than or equal to the right.</returns>
|
||||
public static bool operator <=(Vector4i left, Vector4i right)
|
||||
{
|
||||
if (left.x == right.x)
|
||||
{
|
||||
if (left.y == right.y)
|
||||
{
|
||||
if (left.z == right.z)
|
||||
{
|
||||
return left.w <= right.w;
|
||||
}
|
||||
return left.z < right.z;
|
||||
}
|
||||
return left.y < right.y;
|
||||
}
|
||||
return left.x < right.x;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two <see cref="Vector4i"/> vectors by first checking if
|
||||
/// the X value of the <paramref name="left"/> vector is greater than
|
||||
/// or equal to the X value of the <paramref name="right"/> vector.
|
||||
/// If the X values are exactly equal, then it repeats this check
|
||||
/// with the Y, Z and finally W values of the two vectors.
|
||||
/// This operator is useful for sorting vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The left vector.</param>
|
||||
/// <param name="right">The right vector.</param>
|
||||
/// <returns>Whether or not the left is greater than or equal to the right.</returns>
|
||||
public static bool operator >=(Vector4i left, Vector4i right)
|
||||
{
|
||||
if (left.x == right.x)
|
||||
{
|
||||
if (left.y == right.y)
|
||||
{
|
||||
if (left.z == right.z)
|
||||
{
|
||||
return left.w >= right.w;
|
||||
}
|
||||
return left.z > right.z;
|
||||
}
|
||||
return left.y > right.y;
|
||||
}
|
||||
return left.x > right.x;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts this <see cref="Vector4i"/> to a <see cref="Vector4"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to convert.</param>
|
||||
public static implicit operator Vector4(Vector4i value)
|
||||
{
|
||||
return new Vector4(value.x, value.y, value.z, value.w);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a <see cref="Vector4"/> to a <see cref="Vector4i"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to convert.</param>
|
||||
public static explicit operator Vector4i(Vector4 value)
|
||||
{
|
||||
return new Vector4i(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns <see langword="true"/> if the vector is equal
|
||||
/// to the given object (<see paramref="obj"/>).
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to compare with.</param>
|
||||
/// <returns>Whether or not the vector and the object are equal.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is Vector4i)
|
||||
{
|
||||
return Equals((Vector4i)obj);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns <see langword="true"/> if the vectors are equal.
|
||||
/// </summary>
|
||||
/// <param name="other">The other vector.</param>
|
||||
/// <returns>Whether or not the vectors are equal.</returns>
|
||||
public bool Equals(Vector4i other)
|
||||
{
|
||||
return x == other.x && y == other.y && z == other.z && w == other.w;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serves as the hash function for <see cref="Vector4i"/>.
|
||||
/// </summary>
|
||||
/// <returns>A hash code for this vector.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return y.GetHashCode() ^ x.GetHashCode() ^ z.GetHashCode() ^ w.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts this <see cref="Vector4i"/> to a string.
|
||||
/// </summary>
|
||||
/// <returns>A string representation of this vector.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return $"({x}, {y}, {z}, {w})";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts this <see cref="Vector4i"/> to a string with the given <paramref name="format"/>.
|
||||
/// </summary>
|
||||
/// <returns>A string representation of this vector.</returns>
|
||||
public string ToString(string format)
|
||||
{
|
||||
return $"({x.ToString(format)}, {y.ToString(format)}, {z.ToString(format)}), {w.ToString(format)})";
|
||||
}
|
||||
}
|
||||
}
|
@ -50,6 +50,7 @@
|
||||
<Compile Include="Core\NodePath.cs" />
|
||||
<Compile Include="Core\Object.base.cs" />
|
||||
<Compile Include="Core\Plane.cs" />
|
||||
<Compile Include="Core\Projection.cs" />
|
||||
<Compile Include="Core\Quaternion.cs" />
|
||||
<Compile Include="Core\Rect2.cs" />
|
||||
<Compile Include="Core\Rect2i.cs" />
|
||||
@ -65,6 +66,8 @@
|
||||
<Compile Include="Core\Vector2i.cs" />
|
||||
<Compile Include="Core\Vector3.cs" />
|
||||
<Compile Include="Core\Vector3i.cs" />
|
||||
<Compile Include="Core\Vector4.cs" />
|
||||
<Compile Include="Core\Vector4i.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<!--
|
||||
|
@ -262,7 +262,7 @@ enum {
|
||||
offsetof(Vector4, z) == (sizeof(real_t) * 2) &&
|
||||
offsetof(Vector4, w) == (sizeof(real_t) * 3)),
|
||||
|
||||
MATCHES_Vector4i = (MATCHES_int && (sizeof(Vector4i) == (sizeof(int32_t) * 4i)) &&
|
||||
MATCHES_Vector4i = (MATCHES_int && (sizeof(Vector4i) == (sizeof(int32_t) * 4)) &&
|
||||
offsetof(Vector4i, x) == (sizeof(int32_t) * 0) &&
|
||||
offsetof(Vector4i, y) == (sizeof(int32_t) * 1) &&
|
||||
offsetof(Vector4i, z) == (sizeof(int32_t) * 2) &&
|
||||
|
Loading…
Reference in New Issue
Block a user