mirror of
https://github.com/beefytech/Beef.git
synced 2025-07-04 15:26:00 +02:00
Additional 3d support
This commit is contained in:
parent
369bb0640c
commit
39c140f44a
27 changed files with 4063 additions and 126 deletions
14
BeefLibs/Beefy2D/src/geom/BoundingBox.bf
Normal file
14
BeefLibs/Beefy2D/src/geom/BoundingBox.bf
Normal file
|
@ -0,0 +1,14 @@
|
|||
// This file contains portions of code from the FNA project (github.com/FNA-XNA/FNA),
|
||||
// released under the Microsoft Public License
|
||||
|
||||
namespace Beefy.geom
|
||||
{
|
||||
class BoundingBox
|
||||
{
|
||||
public Vector3 Min;
|
||||
public Vector3 Max;
|
||||
public const int CornerCount = 8;
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -55,6 +55,19 @@ namespace Beefy.geom
|
|||
this.m33 = m33;
|
||||
}
|
||||
|
||||
public static Matrix4 CreateFromColumnMajor(
|
||||
float m00, float m10, float m20, float m30,
|
||||
float m01, float m11, float m21, float m31,
|
||||
float m02, float m12, float m22, float m32,
|
||||
float m03, float m13, float m23, float m33)
|
||||
{
|
||||
return .(
|
||||
m00, m01, m02, m03,
|
||||
m10, m11, m12, m13,
|
||||
m20, m21, m22, m23,
|
||||
m30, m31, m32, m33);
|
||||
}
|
||||
|
||||
public static Matrix4 CreatePerspective(float width, float height, float nearPlaneDistance, float farPlaneDistance)
|
||||
{
|
||||
Matrix4 matrix;
|
||||
|
@ -190,25 +203,23 @@ namespace Beefy.geom
|
|||
public static Matrix4 Multiply(Matrix4 m1, Matrix4 m2)
|
||||
{
|
||||
Matrix4 r;
|
||||
r.m00 = m1.m00 * m2.m00 + m1.m01 * m2.m10 + m1.m02 * m2.m20 + m1.m03 * m2.m30;
|
||||
r.m01 = m1.m00 * m2.m01 + m1.m01 * m2.m11 + m1.m02 * m2.m21 + m1.m03 * m2.m31;
|
||||
r.m02 = m1.m00 * m2.m02 + m1.m01 * m2.m12 + m1.m02 * m2.m22 + m1.m03 * m2.m32;
|
||||
r.m03 = m1.m00 * m2.m03 + m1.m01 * m2.m13 + m1.m02 * m2.m23 + m1.m03 * m2.m33;
|
||||
|
||||
r.m10 = m1.m10 * m2.m00 + m1.m11 * m2.m10 + m1.m12 * m2.m20 + m1.m13 * m2.m30;
|
||||
r.m11 = m1.m10 * m2.m01 + m1.m11 * m2.m11 + m1.m12 * m2.m21 + m1.m13 * m2.m31;
|
||||
r.m12 = m1.m10 * m2.m02 + m1.m11 * m2.m12 + m1.m12 * m2.m22 + m1.m13 * m2.m32;
|
||||
r.m13 = m1.m10 * m2.m03 + m1.m11 * m2.m13 + m1.m12 * m2.m23 + m1.m13 * m2.m33;
|
||||
|
||||
r.m20 = m1.m20 * m2.m00 + m1.m21 * m2.m10 + m1.m22 * m2.m20 + m1.m23 * m2.m30;
|
||||
r.m21 = m1.m20 * m2.m01 + m1.m21 * m2.m11 + m1.m22 * m2.m21 + m1.m23 * m2.m31;
|
||||
r.m22 = m1.m20 * m2.m02 + m1.m21 * m2.m12 + m1.m22 * m2.m22 + m1.m23 * m2.m32;
|
||||
r.m23 = m1.m20 * m2.m03 + m1.m21 * m2.m13 + m1.m22 * m2.m23 + m1.m23 * m2.m33;
|
||||
|
||||
r.m30 = m1.m30 * m2.m00 + m1.m31 * m2.m10 + m1.m32 * m2.m20 + m1.m33 * m2.m30;
|
||||
r.m31 = m1.m30 * m2.m01 + m1.m31 * m2.m11 + m1.m32 * m2.m21 + m1.m33 * m2.m31;
|
||||
r.m32 = m1.m30 * m2.m02 + m1.m31 * m2.m12 + m1.m32 * m2.m22 + m1.m33 * m2.m32;
|
||||
r.m33 = m1.m30 * m2.m03 + m1.m31 * m2.m13 + m1.m32 * m2.m23 + m1.m33 * m2.m33;
|
||||
r.m00 = (((m1.m00 * m2.m00) + (m1.m10 * m2.m01)) + (m1.m20 * m2.m02)) + (m1.m30 * m2.m03);
|
||||
r.m10 = (((m1.m00 * m2.m10) + (m1.m10 * m2.m11)) + (m1.m20 * m2.m12)) + (m1.m30 * m2.m13);
|
||||
r.m20 = (((m1.m00 * m2.m20) + (m1.m10 * m2.m21)) + (m1.m20 * m2.m22)) + (m1.m30 * m2.m23);
|
||||
r.m30 = (((m1.m00 * m2.m30) + (m1.m10 * m2.m31)) + (m1.m20 * m2.m32)) + (m1.m30 * m2.m33);
|
||||
r.m01 = (((m1.m01 * m2.m00) + (m1.m11 * m2.m01)) + (m1.m21 * m2.m02)) + (m1.m31 * m2.m03);
|
||||
r.m11 = (((m1.m01 * m2.m10) + (m1.m11 * m2.m11)) + (m1.m21 * m2.m12)) + (m1.m31 * m2.m13);
|
||||
r.m21 = (((m1.m01 * m2.m20) + (m1.m11 * m2.m21)) + (m1.m21 * m2.m22)) + (m1.m31 * m2.m23);
|
||||
r.m31 = (((m1.m01 * m2.m30) + (m1.m11 * m2.m31)) + (m1.m21 * m2.m32)) + (m1.m31 * m2.m33);
|
||||
r.m02 = (((m1.m02 * m2.m00) + (m1.m12 * m2.m01)) + (m1.m22 * m2.m02)) + (m1.m32 * m2.m03);
|
||||
r.m12 = (((m1.m02 * m2.m10) + (m1.m12 * m2.m11)) + (m1.m22 * m2.m12)) + (m1.m32 * m2.m13);
|
||||
r.m22 = (((m1.m02 * m2.m20) + (m1.m12 * m2.m21)) + (m1.m22 * m2.m22)) + (m1.m32 * m2.m23);
|
||||
r.m32 = (((m1.m02 * m2.m30) + (m1.m12 * m2.m31)) + (m1.m22 * m2.m32)) + (m1.m32 * m2.m33);
|
||||
r.m03 = (((m1.m03 * m2.m00) + (m1.m13 * m2.m01)) + (m1.m23 * m2.m02)) + (m1.m33 * m2.m03);
|
||||
r.m13 = (((m1.m03 * m2.m10) + (m1.m13 * m2.m11)) + (m1.m23 * m2.m12)) + (m1.m33 * m2.m13);
|
||||
r.m23 = (((m1.m03 * m2.m20) + (m1.m13 * m2.m21)) + (m1.m23 * m2.m22)) + (m1.m33 * m2.m23);
|
||||
r.m33 = (((m1.m03 * m2.m30) + (m1.m13 * m2.m31)) + (m1.m23 * m2.m32)) + (m1.m33 * m2.m33);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -489,5 +500,730 @@ namespace Beefy.geom
|
|||
r20, r21, r22, r23,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
public static void Invert(Matrix4 matrix, out Matrix4 result)
|
||||
{
|
||||
float num1 = matrix.m00;
|
||||
float num2 = matrix.m10;
|
||||
float num3 = matrix.m20;
|
||||
float num4 = matrix.m30;
|
||||
float num5 = matrix.m01;
|
||||
float num6 = matrix.m11;
|
||||
float num7 = matrix.m21;
|
||||
float num8 = matrix.m31;
|
||||
float num9 = matrix.m02;
|
||||
float num10 = matrix.m12;
|
||||
float num11 = matrix.m22;
|
||||
float num12 = matrix.m32;
|
||||
float num13 = matrix.m03;
|
||||
float num14 = matrix.m13;
|
||||
float num15 = matrix.m23;
|
||||
float num16 = matrix.m33;
|
||||
float num17 = (float) ((double) num11 * (double) num16 - (double) num12 * (double) num15);
|
||||
float num18 = (float) ((double) num10 * (double) num16 - (double) num12 * (double) num14);
|
||||
float num19 = (float) ((double) num10 * (double) num15 - (double) num11 * (double) num14);
|
||||
float num20 = (float) ((double) num9 * (double) num16 - (double) num12 * (double) num13);
|
||||
float num21 = (float) ((double) num9 * (double) num15 - (double) num11 * (double) num13);
|
||||
float num22 = (float) ((double) num9 * (double) num14 - (double) num10 * (double) num13);
|
||||
float num23 = (float) ((double) num6 * (double) num17 - (double) num7 * (double) num18 + (double) num8 * (double) num19);
|
||||
float num24 = (float) -((double) num5 * (double) num17 - (double) num7 * (double) num20 + (double) num8 * (double) num21);
|
||||
float num25 = (float) ((double) num5 * (double) num18 - (double) num6 * (double) num20 + (double) num8 * (double) num22);
|
||||
float num26 = (float) -((double) num5 * (double) num19 - (double) num6 * (double) num21 + (double) num7 * (double) num22);
|
||||
float num27 = (float) (1.0 / ((double) num1 * (double) num23 + (double) num2 * (double) num24 + (double) num3 * (double) num25 + (double) num4 * (double) num26));
|
||||
|
||||
result.m00 = num23 * num27;
|
||||
result.m01 = num24 * num27;
|
||||
result.m02 = num25 * num27;
|
||||
result.m03 = num26 * num27;
|
||||
result.m10 = (float)(-((double) num2 * (double) num17 - (double) num3 * (double) num18 + (double) num4 * (double) num19) * num27);
|
||||
result.m11 = (float) ((double) num1 * (double) num17 - (double) num3 * (double) num20 + (double) num4 * (double) num21) * num27;
|
||||
result.m12 = (float)(-((double) num1 * (double) num18 - (double) num2 * (double) num20 + (double) num4 * (double) num22) * num27);
|
||||
result.m13 = (float) ((double) num1 * (double) num19 - (double) num2 * (double) num21 + (double) num3 * (double) num22) * num27;
|
||||
float num28 = (float) ((double) num7 * (double) num16 - (double) num8 * (double) num15);
|
||||
float num29 = (float) ((double) num6 * (double) num16 - (double) num8 * (double) num14);
|
||||
float num30 = (float) ((double) num6 * (double) num15 - (double) num7 * (double) num14);
|
||||
float num31 = (float) ((double) num5 * (double) num16 - (double) num8 * (double) num13);
|
||||
float num32 = (float) ((double) num5 * (double) num15 - (double) num7 * (double) num13);
|
||||
float num33 = (float) ((double) num5 * (double) num14 - (double) num6 * (double) num13);
|
||||
result.m20 = (float) ((double) num2 * (double) num28 - (double) num3 * (double) num29 + (double) num4 * (double) num30) * num27;
|
||||
result.m21 = (float)(-((double) num1 * (double) num28 - (double) num3 * (double) num31 + (double) num4 * (double) num32) * num27);
|
||||
result.m22 = (float) ((double) num1 * (double) num29 - (double) num2 * (double) num31 + (double) num4 * (double) num33) * num27;
|
||||
result.m23 = (float)(-((double) num1 * (double) num30 - (double) num2 * (double) num32 + (double) num3 * (double) num33) * num27);
|
||||
float num34 = (float) ((double) num7 * (double) num12 - (double) num8 * (double) num11);
|
||||
float num35 = (float) ((double) num6 * (double) num12 - (double) num8 * (double) num10);
|
||||
float num36 = (float) ((double) num6 * (double) num11 - (double) num7 * (double) num10);
|
||||
float num37 = (float) ((double) num5 * (double) num12 - (double) num8 * (double) num9);
|
||||
float num38 = (float) ((double) num5 * (double) num11 - (double) num7 * (double) num9);
|
||||
float num39 = (float) ((double) num5 * (double) num10 - (double) num6 * (double) num9);
|
||||
result.m30 = (float)(-((double) num2 * (double) num34 - (double) num3 * (double) num35 + (double) num4 * (double) num36) * num27);
|
||||
result.m31 = (float) ((double) num1 * (double) num34 - (double) num3 * (double) num37 + (double) num4 * (double) num38) * num27;
|
||||
result.m32 = (float)(-((double) num1 * (double) num35 - (double) num2 * (double) num37 + (double) num4 * (double) num39) * num27);
|
||||
result.m33 = (float) ((double) num1 * (double) num36 - (double) num2 * (double) num38 + (double) num3 * (double) num39) * num27;
|
||||
|
||||
/*
|
||||
|
||||
|
||||
///
|
||||
// Use Laplace expansion theorem to calculate the inverse of a 4x4 matrix
|
||||
//
|
||||
// 1. Calculate the 2x2 determinants needed the 4x4 determinant based on the 2x2 determinants
|
||||
// 3. Create the adjugate matrix, which satisfies: A * adj(A) = det(A) * I
|
||||
// 4. Divide adjugate matrix with the determinant to find the inverse
|
||||
|
||||
float det1, det2, det3, det4, det5, det6, det7, det8, det9, det10, det11, det12;
|
||||
float detMatrix;
|
||||
FindDeterminants(ref matrix, out detMatrix, out det1, out det2, out det3, out det4, out det5, out det6,
|
||||
out det7, out det8, out det9, out det10, out det11, out det12);
|
||||
|
||||
float invDetMatrix = 1f / detMatrix;
|
||||
|
||||
Matrix ret; // Allow for matrix and result to point to the same structure
|
||||
|
||||
ret.M11 = (matrix.M22*det12 - matrix.M23*det11 + matrix.M24*det10) * invDetMatrix;
|
||||
ret.M12 = (-matrix.M12*det12 + matrix.M13*det11 - matrix.M14*det10) * invDetMatrix;
|
||||
ret.M13 = (matrix.M42*det6 - matrix.M43*det5 + matrix.M44*det4) * invDetMatrix;
|
||||
ret.M14 = (-matrix.M32*det6 + matrix.M33*det5 - matrix.M34*det4) * invDetMatrix;
|
||||
ret.M21 = (-matrix.M21*det12 + matrix.M23*det9 - matrix.M24*det8) * invDetMatrix;
|
||||
ret.M22 = (matrix.M11*det12 - matrix.M13*det9 + matrix.M14*det8) * invDetMatrix;
|
||||
ret.M23 = (-matrix.M41*det6 + matrix.M43*det3 - matrix.M44*det2) * invDetMatrix;
|
||||
ret.M24 = (matrix.M31*det6 - matrix.M33*det3 + matrix.M34*det2) * invDetMatrix;
|
||||
ret.M31 = (matrix.M21*det11 - matrix.M22*det9 + matrix.M24*det7) * invDetMatrix;
|
||||
ret.M32 = (-matrix.M11*det11 + matrix.M12*det9 - matrix.M14*det7) * invDetMatrix;
|
||||
ret.M33 = (matrix.M41*det5 - matrix.M42*det3 + matrix.M44*det1) * invDetMatrix;
|
||||
ret.M34 = (-matrix.M31*det5 + matrix.M32*det3 - matrix.M34*det1) * invDetMatrix;
|
||||
ret.M41 = (-matrix.M21*det10 + matrix.M22*det8 - matrix.M23*det7) * invDetMatrix;
|
||||
ret.M42 = (matrix.M11*det10 - matrix.M12*det8 + matrix.M13*det7) * invDetMatrix;
|
||||
ret.M43 = (-matrix.M41*det4 + matrix.M42*det2 - matrix.M43*det1) * invDetMatrix;
|
||||
ret.M44 = (matrix.M31*det4 - matrix.M32*det2 + matrix.M33*det1) * invDetMatrix;
|
||||
|
||||
result = ret;
|
||||
*/
|
||||
}
|
||||
|
||||
public static Matrix4 Invert(Matrix4 matrix)
|
||||
{
|
||||
Invert(matrix, var outMatrix);
|
||||
return outMatrix;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decomposes this matrix to translation, rotation and scale elements. Returns <c>true</c> if matrix can be decomposed; <c>false</c> otherwise.
|
||||
/// </summary>
|
||||
/// <param name="scale">Scale vector as an output parameter.
|
||||
/// <param name="rotation">Rotation quaternion as an output parameter.
|
||||
/// <param name="translation">Translation vector as an output parameter.
|
||||
/// <returns><c>true</c> if matrix can be decomposed; <c>false</c> otherwise.</returns>
|
||||
public bool Decompose(
|
||||
out Vector3 scale,
|
||||
out Quaternion rotation,
|
||||
out Vector3 translation
|
||||
) {
|
||||
translation.mX = m03;
|
||||
translation.mY = m13;
|
||||
translation.mZ = m23;
|
||||
|
||||
float xs = (Math.Sign(m00 * m10 * m20 * m30) < 0) ? -1 : 1;
|
||||
float ys = (Math.Sign(m01 * m11 * m21 * m31) < 0) ? -1 : 1;
|
||||
float zs = (Math.Sign(m02 * m12 * m22 * m32) < 0) ? -1 : 1;
|
||||
|
||||
scale.mX = xs * (float) Math.Sqrt(m00 * m00 + m10 * m10 + m20 * m20);
|
||||
scale.mY = ys * (float) Math.Sqrt(m01 * m01 + m11 * m11 + m21 * m21);
|
||||
scale.mZ = zs * (float) Math.Sqrt(m02 * m02 + m12 * m12 + m22 * m22);
|
||||
|
||||
if (Math.WithinEpsilon(scale.mX, 0.0f) ||
|
||||
Math.WithinEpsilon(scale.mY, 0.0f) ||
|
||||
Math.WithinEpsilon(scale.mZ, 0.0f) )
|
||||
{
|
||||
rotation = Quaternion.Identity;
|
||||
return false;
|
||||
}
|
||||
|
||||
Matrix4 m1 = Matrix4.CreateFromColumnMajor(
|
||||
m00 / scale.mX, m10 / scale.mX, m20 / scale.mX, 0,
|
||||
m01 / scale.mY, m11 / scale.mY, m21 / scale.mY, 0,
|
||||
m02 / scale.mZ, m12 / scale.mZ, m22 / scale.mZ, 0,
|
||||
0, 0, 0, 1
|
||||
);
|
||||
|
||||
rotation = Quaternion.CreateFromRotationMatrix(m1);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a determinant of this matrix.
|
||||
/// </summary>
|
||||
/// <returns>Determinant of this matrix</returns>
|
||||
/// <remarks>See more about determinant here - http://en.wikipedia.org/wiki/Determinant.
|
||||
/// </remarks>
|
||||
public float Determinant()
|
||||
{
|
||||
float num18 = (m22 * m33) - (m32 * m23);
|
||||
float num17 = (m12 * m33) - (m32 * m13);
|
||||
float num16 = (m12 * m23) - (m22 * m13);
|
||||
float num15 = (m02 * m33) - (m32 * m03);
|
||||
float num14 = (m02 * m23) - (m22 * m03);
|
||||
float num13 = (m02 * m13) - (m12 * m03);
|
||||
return (
|
||||
(
|
||||
(
|
||||
(m00 * (((m11 * num18) - (m21 * num17)) + (m31 * num16))) -
|
||||
(m10 * (((m01 * num18) - (m21 * num15)) + (m31 * num14)))
|
||||
) + (m20 * (((m01 * num17) - (m11 * num15)) + (m31 * num13)))
|
||||
) - (m30 * (((m01 * num16) - (m11 * num14)) + (m21 * num13)))
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new matrix for spherical billboarding that rotates around specified object position.
|
||||
/// </summary>
|
||||
/// <param name="objectPosition">Position of billboard object. It will rotate around that vector.
|
||||
/// <param name="cameraPosition">The camera position.
|
||||
/// <param name="cameraUpVector">The camera up vector.
|
||||
/// <param name="cameraForwardVector">Optional camera forward vector.
|
||||
/// <returns>The matrix for spherical billboarding.</returns>
|
||||
public static Matrix4 CreateBillboard(
|
||||
Vector3 objectPosition,
|
||||
Vector3 cameraPosition,
|
||||
Vector3 cameraUpVector,
|
||||
Nullable<Vector3> cameraForwardVector
|
||||
) {
|
||||
Matrix4 result;
|
||||
|
||||
// Delegate to the other overload of the function to do the work
|
||||
CreateBillboard(
|
||||
objectPosition,
|
||||
cameraPosition,
|
||||
cameraUpVector,
|
||||
cameraForwardVector,
|
||||
out result
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new matrix for spherical billboarding that rotates around specified object position.
|
||||
/// </summary>
|
||||
/// <param name="objectPosition">Position of billboard object. It will rotate around that vector.
|
||||
/// <param name="cameraPosition">The camera position.
|
||||
/// <param name="cameraUpVector">The camera up vector.
|
||||
/// <param name="cameraForwardVector">Optional camera forward vector.
|
||||
/// <param name="result">The matrix for spherical billboarding as an output parameter.
|
||||
public static void CreateBillboard(
|
||||
Vector3 objectPosition,
|
||||
Vector3 cameraPosition,
|
||||
Vector3 cameraUpVector,
|
||||
Vector3? cameraForwardVector,
|
||||
out Matrix4 result
|
||||
) {
|
||||
Vector3 vector;
|
||||
Vector3 vector2;
|
||||
Vector3 vector3;
|
||||
vector.mX = objectPosition.mX - cameraPosition.mX;
|
||||
vector.mY = objectPosition.mY - cameraPosition.mY;
|
||||
vector.mZ = objectPosition.mZ - cameraPosition.mZ;
|
||||
float num = vector.LengthSquared;
|
||||
if (num < 0.0001f)
|
||||
{
|
||||
vector = cameraForwardVector.HasValue ?
|
||||
-cameraForwardVector.Value :
|
||||
Vector3.Forward;
|
||||
}
|
||||
else
|
||||
{
|
||||
vector *= (float) (1f / ((float) Math.Sqrt((double) num)));
|
||||
}
|
||||
vector3 = Vector3.Cross(cameraUpVector, vector);
|
||||
vector3.Normalize();
|
||||
vector2 = Vector3.Cross(vector, vector3);
|
||||
result.m00 = vector3.mX;
|
||||
result.m10 = vector3.mY;
|
||||
result.m20 = vector3.mZ;
|
||||
result.m30 = 0;
|
||||
result.m01 = vector2.mX;
|
||||
result.m11 = vector2.mY;
|
||||
result.m21 = vector2.mZ;
|
||||
result.m31 = 0;
|
||||
result.m02 = vector.mX;
|
||||
result.m12 = vector.mY;
|
||||
result.m22 = vector.mZ;
|
||||
result.m32 = 0;
|
||||
result.m03 = objectPosition.mX;
|
||||
result.m13 = objectPosition.mY;
|
||||
result.m23 = objectPosition.mZ;
|
||||
result.m33 = 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new matrix for cylindrical billboarding that rotates around specified axis.
|
||||
/// </summary>
|
||||
/// <param name="objectPosition">Object position the billboard will rotate around.
|
||||
/// <param name="cameraPosition">Camera position.
|
||||
/// <param name="rotateAxis">Axis of billboard for rotation.
|
||||
/// <param name="cameraForwardVector">Optional camera forward vector.
|
||||
/// <param name="objectForwardVector">Optional object forward vector.
|
||||
/// <returns>The matrix for cylindrical billboarding.</returns>
|
||||
public static Matrix4 CreateConstrainedBillboard(
|
||||
Vector3 objectPosition,
|
||||
Vector3 cameraPosition,
|
||||
Vector3 rotateAxis,
|
||||
Nullable<Vector3> cameraForwardVector,
|
||||
Nullable<Vector3> objectForwardVector
|
||||
) {
|
||||
Matrix4 result;
|
||||
CreateConstrainedBillboard(
|
||||
objectPosition,
|
||||
cameraPosition,
|
||||
rotateAxis,
|
||||
cameraForwardVector,
|
||||
objectForwardVector,
|
||||
out result
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new matrix for cylindrical billboarding that rotates around specified axis.
|
||||
/// </summary>
|
||||
/// <param name="objectPosition">Object position the billboard will rotate around.
|
||||
/// <param name="cameraPosition">Camera position.
|
||||
/// <param name="rotateAxis">Axis of billboard for rotation.
|
||||
/// <param name="cameraForwardVector">Optional camera forward vector.
|
||||
/// <param name="objectForwardVector">Optional object forward vector.
|
||||
/// <param name="result">The matrix for cylindrical billboarding as an output parameter.
|
||||
public static void CreateConstrainedBillboard(
|
||||
Vector3 objectPosition,
|
||||
Vector3 cameraPosition,
|
||||
Vector3 rotateAxis,
|
||||
Vector3? cameraForwardVector,
|
||||
Vector3? objectForwardVector,
|
||||
out Matrix4 result
|
||||
) {
|
||||
float num;
|
||||
Vector3 vector;
|
||||
Vector3 vector2;
|
||||
Vector3 vector3;
|
||||
vector2.mX = objectPosition.mX - cameraPosition.mX;
|
||||
vector2.mY = objectPosition.mY - cameraPosition.mY;
|
||||
vector2.mZ = objectPosition.mZ - cameraPosition.mZ;
|
||||
float num2 = vector2.LengthSquared;
|
||||
if (num2 < 0.0001f)
|
||||
{
|
||||
vector2 = cameraForwardVector.HasValue ?
|
||||
-cameraForwardVector.Value :
|
||||
Vector3.Forward;
|
||||
}
|
||||
else
|
||||
{
|
||||
vector2 *= (float) (1f / ((float) Math.Sqrt((double) num2)));
|
||||
}
|
||||
Vector3 vector4 = rotateAxis;
|
||||
num = Vector3.Dot(rotateAxis, vector2);
|
||||
if (Math.Abs(num) > 0.9982547f)
|
||||
{
|
||||
if (objectForwardVector.HasValue)
|
||||
{
|
||||
vector = objectForwardVector.Value;
|
||||
num = Vector3.Dot(rotateAxis, vector);
|
||||
if (Math.Abs(num) > 0.9982547f)
|
||||
{
|
||||
num = (
|
||||
(rotateAxis.mX * Vector3.Forward.mX) +
|
||||
(rotateAxis.mY * Vector3.Forward.mY)
|
||||
) + (rotateAxis.mZ * Vector3.Forward.mZ);
|
||||
vector = (Math.Abs(num) > 0.9982547f) ?
|
||||
Vector3.Right :
|
||||
Vector3.Forward;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
num = (
|
||||
(rotateAxis.mX * Vector3.Forward.mX) +
|
||||
(rotateAxis.mY * Vector3.Forward.mY)
|
||||
) + (rotateAxis.mZ * Vector3.Forward.mZ);
|
||||
vector = (Math.Abs(num) > 0.9982547f) ?
|
||||
Vector3.Right :
|
||||
Vector3.Forward;
|
||||
}
|
||||
vector3 = Vector3.Cross(rotateAxis, vector);
|
||||
vector3.Normalize();
|
||||
vector = Vector3.Cross(vector3, rotateAxis);
|
||||
vector.Normalize();
|
||||
}
|
||||
else
|
||||
{
|
||||
vector3 = Vector3.Cross(rotateAxis, vector2);
|
||||
vector3.Normalize();
|
||||
vector = Vector3.Cross(vector3, vector4);
|
||||
vector.Normalize();
|
||||
}
|
||||
|
||||
result.m00 = vector3.mX;
|
||||
result.m10 = vector3.mY;
|
||||
result.m20 = vector3.mZ;
|
||||
result.m30 = 0;
|
||||
result.m01 = vector4.mX;
|
||||
result.m11 = vector4.mY;
|
||||
result.m21 = vector4.mZ;
|
||||
result.m31 = 0;
|
||||
result.m02 = vector.mX;
|
||||
result.m12 = vector.mY;
|
||||
result.m22 = vector.mZ;
|
||||
result.m32 = 0;
|
||||
result.m03 = objectPosition.mX;
|
||||
result.m13 = objectPosition.mY;
|
||||
result.m23 = objectPosition.mZ;
|
||||
result.m33 = 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new matrix which contains the rotation moment around specified axis.
|
||||
/// </summary>
|
||||
/// <param name="axis">The axis of rotation.
|
||||
/// <param name="angle">The angle of rotation in radians.
|
||||
/// <returns>The rotation matrix.</returns>
|
||||
public static Matrix4 CreateFromAxisAngle(Vector3 axis, float angle)
|
||||
{
|
||||
Matrix4 result;
|
||||
CreateFromAxisAngle(axis, angle, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new matrix which contains the rotation moment around specified axis.
|
||||
/// </summary>
|
||||
/// <param name="axis">The axis of rotation.
|
||||
/// <param name="angle">The angle of rotation in radians.
|
||||
/// <param name="result">The rotation matrix as an output parameter.
|
||||
public static void CreateFromAxisAngle(
|
||||
Vector3 axis,
|
||||
float angle,
|
||||
out Matrix4 result
|
||||
) {
|
||||
float x = axis.mX;
|
||||
float y = axis.mY;
|
||||
float z = axis.mZ;
|
||||
float num2 = (float) Math.Sin((double) angle);
|
||||
float num = (float) Math.Cos((double) angle);
|
||||
float num11 = x * x;
|
||||
float num10 = y * y;
|
||||
float num9 = z * z;
|
||||
float num8 = x * y;
|
||||
float num7 = x * z;
|
||||
float num6 = y * z;
|
||||
result.m00 = num11 + (num * (1f - num11));
|
||||
result.m10 = (num8 - (num * num8)) + (num2 * z);
|
||||
result.m20 = (num7 - (num * num7)) - (num2 * y);
|
||||
result.m30 = 0;
|
||||
result.m01 = (num8 - (num * num8)) - (num2 * z);
|
||||
result.m11 = num10 + (num * (1f - num10));
|
||||
result.m21 = (num6 - (num * num6)) + (num2 * x);
|
||||
result.m31 = 0;
|
||||
result.m02 = (num7 - (num * num7)) + (num2 * y);
|
||||
result.m12 = (num6 - (num * num6)) - (num2 * x);
|
||||
result.m22 = num9 + (num * (1f - num9));
|
||||
result.m32 = 0;
|
||||
result.m03 = 0;
|
||||
result.m13 = 0;
|
||||
result.m23 = 0;
|
||||
result.m33 = 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new rotation matrix from a <see cref="Quaternion"/>.
|
||||
/// </summary>
|
||||
/// <param name="quaternion"><see cref="Quaternion"/> of rotation moment.
|
||||
/// <returns>The rotation matrix.</returns>
|
||||
public static Matrix4 CreateFromQuaternion(Quaternion quaternion)
|
||||
{
|
||||
Matrix4 result;
|
||||
CreateFromQuaternion(quaternion, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new rotation matrix from a <see cref="Quaternion"/>.
|
||||
/// </summary>
|
||||
/// <param name="quaternion"><see cref="Quaternion"/> of rotation moment.
|
||||
/// <param name="result">The rotation matrix as an output parameter.
|
||||
public static void CreateFromQuaternion(Quaternion quaternion, out Matrix4 result)
|
||||
{
|
||||
float num9 = quaternion.mX * quaternion.mX;
|
||||
float num8 = quaternion.mY * quaternion.mY;
|
||||
float num7 = quaternion.mZ * quaternion.mZ;
|
||||
float num6 = quaternion.mX * quaternion.mY;
|
||||
float num5 = quaternion.mZ * quaternion.mW;
|
||||
float num4 = quaternion.mZ * quaternion.mX;
|
||||
float num3 = quaternion.mY * quaternion.mW;
|
||||
float num2 = quaternion.mY * quaternion.mZ;
|
||||
float num = quaternion.mX * quaternion.mW;
|
||||
result.m00 = 1f - (2f * (num8 + num7));
|
||||
result.m10 = 2f * (num6 + num5);
|
||||
result.m20 = 2f * (num4 - num3);
|
||||
result.m30 = 0f;
|
||||
result.m01 = 2f * (num6 - num5);
|
||||
result.m11 = 1f - (2f * (num7 + num9));
|
||||
result.m21 = 2f * (num2 + num);
|
||||
result.m31 = 0f;
|
||||
result.m02 = 2f * (num4 + num3);
|
||||
result.m12 = 2f * (num2 - num);
|
||||
result.m22 = 1f - (2f * (num8 + num9));
|
||||
result.m32 = 0f;
|
||||
result.m03 = 0f;
|
||||
result.m13 = 0f;
|
||||
result.m23 = 0f;
|
||||
result.m33 = 1f;
|
||||
}
|
||||
|
||||
/// Creates a new rotation matrix from the specified yaw, pitch and roll values.
|
||||
/// @param yaw The yaw rotation value in radians.
|
||||
/// @param pitch The pitch rotation value in radians.
|
||||
/// @param roll The roll rotation value in radians.
|
||||
/// @returns The rotation matrix
|
||||
/// @remarks For more information about yaw, pitch and roll visit http://en.wikipedia.org/wiki/Euler_angles.
|
||||
public static Matrix4 CreateFromYawPitchRoll(float yaw, float pitch, float roll)
|
||||
{
|
||||
Matrix4 matrix;
|
||||
CreateFromYawPitchRoll(yaw, pitch, roll, out matrix);
|
||||
return matrix;
|
||||
}
|
||||
|
||||
/// Creates a new rotation matrix from the specified yaw, pitch and roll values.
|
||||
/// @param yaw The yaw rotation value in radians.
|
||||
/// @param pitch The pitch rotation value in radians.
|
||||
/// @param roll The roll rotation value in radians.
|
||||
/// @param result The rotation matrix as an output parameter.
|
||||
/// @remarks>For more information about yaw, pitch and roll visit http://en.wikipedia.org/wiki/Euler_angles.
|
||||
public static void CreateFromYawPitchRoll(
|
||||
float yaw,
|
||||
float pitch,
|
||||
float roll,
|
||||
out Matrix4 result
|
||||
) {
|
||||
Quaternion quaternion;
|
||||
Quaternion.CreateFromYawPitchRoll(yaw, pitch, roll, out quaternion);
|
||||
CreateFromQuaternion(quaternion, out result);
|
||||
}
|
||||
|
||||
/// Creates a new viewing matrix.
|
||||
/// @param cameraPosition Position of the camera.
|
||||
/// @param cameraTarget Lookup vector of the camera.
|
||||
/// @param cameraUpVector The direction of the upper edge of the camera.
|
||||
/// @returns The viewing matrix.
|
||||
public static Matrix4 CreateLookAt(
|
||||
Vector3 cameraPosition,
|
||||
Vector3 cameraTarget,
|
||||
Vector3 cameraUpVector
|
||||
) {
|
||||
Matrix4 matrix;
|
||||
CreateLookAt(cameraPosition, cameraTarget, cameraUpVector, out matrix);
|
||||
return matrix;
|
||||
}
|
||||
|
||||
/// Creates a new viewing matrix.
|
||||
/// @param cameraPosition Position of the camera.
|
||||
/// @param cameraTarget Lookup vector of the camera.
|
||||
/// @param cameraUpVector The direction of the upper edge of the camera.
|
||||
/// @param result The viewing matrix as an output parameter.
|
||||
public static void CreateLookAt(
|
||||
Vector3 cameraPosition,
|
||||
Vector3 cameraTarget,
|
||||
Vector3 cameraUpVector,
|
||||
out Matrix4 result
|
||||
) {
|
||||
Vector3 vectorA = Vector3.Normalize(cameraPosition - cameraTarget);
|
||||
Vector3 vectorB = Vector3.Normalize(Vector3.Cross(cameraUpVector, vectorA));
|
||||
Vector3 vectorC = Vector3.Cross(vectorA, vectorB);
|
||||
result.m00 = vectorB.mX;
|
||||
result.m10 = vectorC.mX;
|
||||
result.m20 = vectorA.mX;
|
||||
result.m30 = 0f;
|
||||
result.m01 = vectorB.mY;
|
||||
result.m11 = vectorC.mY;
|
||||
result.m21 = vectorA.mY;
|
||||
result.m31 = 0f;
|
||||
result.m02 = vectorB.mZ;
|
||||
result.m12 = vectorC.mZ;
|
||||
result.m22 = vectorA.mZ;
|
||||
result.m32 = 0f;
|
||||
result.m03 = -Vector3.Dot(vectorB, cameraPosition);
|
||||
result.m13 = -Vector3.Dot(vectorC, cameraPosition);
|
||||
result.m23 = -Vector3.Dot(vectorA, cameraPosition);
|
||||
result.m33 = 1f;
|
||||
}
|
||||
|
||||
/// Creates a new projection matrix for orthographic view.
|
||||
/// @param width Width of the viewing volume.
|
||||
/// @param height Height of the viewing volume.
|
||||
/// @param zNearPlane Depth of the near plane.
|
||||
/// @param zFarPlane Depth of the far plane.
|
||||
/// @returns The new projection matrix for orthographic view.</returns>
|
||||
public static Matrix4 CreateOrthographic(
|
||||
float width,
|
||||
float height,
|
||||
float zNearPlane,
|
||||
float zFarPlane
|
||||
) {
|
||||
Matrix4 matrix;
|
||||
CreateOrthographic(width, height, zNearPlane, zFarPlane, out matrix);
|
||||
return matrix;
|
||||
}
|
||||
|
||||
/// Creates a new projection matrix for orthographic view.
|
||||
/// @param width Width of the viewing volume.
|
||||
/// @param height Height of the viewing volume.
|
||||
/// @param zNearPlane Depth of the near plane.
|
||||
/// @param zFarPlane Depth of the far plane.
|
||||
/// @param result The new projection matrix for orthographic view as an output parameter.
|
||||
public static void CreateOrthographic(
|
||||
float width,
|
||||
float height,
|
||||
float zNearPlane,
|
||||
float zFarPlane,
|
||||
out Matrix4 result
|
||||
) {
|
||||
result.m00 = 2f / width;
|
||||
result.m10 = result.m20 = result.m30 = 0f;
|
||||
result.m11 = 2f / height;
|
||||
result.m01 = result.m21 = result.m31 = 0f;
|
||||
result.m22 = 1f / (zNearPlane - zFarPlane);
|
||||
result.m02 = result.m12 = result.m32 = 0f;
|
||||
result.m03 = result.m13 = 0f;
|
||||
result.m23 = zNearPlane / (zNearPlane - zFarPlane);
|
||||
result.m33 = 1f;
|
||||
}
|
||||
|
||||
/// Creates a new projection matrix for customized orthographic view.
|
||||
/// @param left Lower x-value at the near plane.
|
||||
/// @param right Upper x-value at the near plane.
|
||||
/// @param bottom Lower y-coordinate at the near plane.
|
||||
/// @param top Upper y-value at the near plane.
|
||||
/// @param zNearPlane Depth of the near plane.
|
||||
/// @param zFarPlane Depth of the far plane.
|
||||
/// @returns The new projection matrix for customized orthographic view.</returns>
|
||||
public static Matrix4 CreateOrthographicOffCenter(
|
||||
float left,
|
||||
float right,
|
||||
float bottom,
|
||||
float top,
|
||||
float zNearPlane,
|
||||
float zFarPlane
|
||||
) {
|
||||
Matrix4 matrix;
|
||||
CreateOrthographicOffCenter(
|
||||
left,
|
||||
right,
|
||||
bottom,
|
||||
top,
|
||||
zNearPlane,
|
||||
zFarPlane,
|
||||
out matrix
|
||||
);
|
||||
return matrix;
|
||||
}
|
||||
|
||||
/// Creates a new projection matrix for customized orthographic view.
|
||||
/// @param left Lower x-value at the near plane.
|
||||
/// @param right Upper x-value at the near plane.
|
||||
/// @param bottom Lower y-coordinate at the near plane.
|
||||
/// @param top Upper y-value at the near plane.
|
||||
/// @param zNearPlane Depth of the near plane.
|
||||
/// @param zFarPlane Depth of the far plane.
|
||||
/// @param result The new projection matrix for customized orthographic view as an output parameter.
|
||||
public static void CreateOrthographicOffCenter(
|
||||
float left,
|
||||
float right,
|
||||
float bottom,
|
||||
float top,
|
||||
float zNearPlane,
|
||||
float zFarPlane,
|
||||
out Matrix4 result
|
||||
)
|
||||
{
|
||||
result.m00 = (float) (2.0 / ((double) right - (double) left));
|
||||
result.m10 = 0.0f;
|
||||
result.m20 = 0.0f;
|
||||
result.m30 = 0.0f;
|
||||
result.m01 = 0.0f;
|
||||
result.m11 = (float) (2.0 / ((double) top - (double) bottom));
|
||||
result.m21 = 0.0f;
|
||||
result.m31 = 0.0f;
|
||||
result.m02 = 0.0f;
|
||||
result.m12 = 0.0f;
|
||||
result.m22 = (float) (1.0 / ((double) zNearPlane - (double) zFarPlane));
|
||||
result.m32 = 0.0f;
|
||||
result.m03 = (float) (
|
||||
((double) left + (double) right) /
|
||||
((double) left - (double) right)
|
||||
);
|
||||
result.m13 = (float) (
|
||||
((double) top + (double) bottom) /
|
||||
((double) bottom - (double) top)
|
||||
);
|
||||
result.m23 = (float) (
|
||||
(double) zNearPlane /
|
||||
((double) zNearPlane - (double) zFarPlane)
|
||||
);
|
||||
result.m33 = 1.0f;
|
||||
}
|
||||
|
||||
/// Creates a new matrix that flattens geometry into a specified <see cref="Plane"/> as if casting a shadow from a specified light source.
|
||||
/// @param lightDirection A vector specifying the direction from which the light that will cast the shadow is coming.
|
||||
/// @param plane The plane onto which the new matrix should flatten geometry so as to cast a shadow.
|
||||
/// @returns>A matrix that can be used to flatten geometry onto the specified plane from the specified direction.
|
||||
public static Matrix4 CreateShadow(Vector3 lightDirection, Plane plane)
|
||||
{
|
||||
Matrix4 result;
|
||||
result = CreateShadow(lightDirection, plane);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Creates a new matrix that flattens geometry into a specified <see cref="Plane"/> as if casting a shadow from a specified light source.
|
||||
/// @param lightDirection A vector specifying the direction from which the light that will cast the shadow is coming.
|
||||
/// @param plane The plane onto which the new matrix should flatten geometry so as to cast a shadow.
|
||||
/// @param result A matrix that can be used to flatten geometry onto the specified plane from the specified direction as an output parameter.
|
||||
public static void CreateShadow(
|
||||
Vector3 lightDirection,
|
||||
Plane plane,
|
||||
out Matrix4 result)
|
||||
{
|
||||
float dot = (
|
||||
(plane.Normal.mX * lightDirection.mX) +
|
||||
(plane.Normal.mY * lightDirection.mY) +
|
||||
(plane.Normal.mZ * lightDirection.mZ)
|
||||
);
|
||||
float x = -plane.Normal.mX;
|
||||
float y = -plane.Normal.mY;
|
||||
float z = -plane.Normal.mZ;
|
||||
float d = -plane.D;
|
||||
|
||||
result.m00 = (x * lightDirection.mX) + dot;
|
||||
result.m10 = x * lightDirection.mY;
|
||||
result.m20 = x * lightDirection.mZ;
|
||||
result.m30 = 0;
|
||||
result.m01 = y * lightDirection.mX;
|
||||
result.m11 = (y * lightDirection.mY) + dot;
|
||||
result.m21 = y * lightDirection.mZ;
|
||||
result.m31 = 0;
|
||||
result.m02 = z * lightDirection.mX;
|
||||
result.m12 = z * lightDirection.mY;
|
||||
result.m22 = (z * lightDirection.mZ) + dot;
|
||||
result.m32 = 0;
|
||||
result.m03 = d * lightDirection.mX;
|
||||
result.m13 = d * lightDirection.mY;
|
||||
result.m23 = d * lightDirection.mZ;
|
||||
result.m33 = dot;
|
||||
}
|
||||
|
||||
public override void ToString(System.String strBuffer)
|
||||
{
|
||||
for (int row < 4)
|
||||
for (int col < 4)
|
||||
{
|
||||
#unwarn
|
||||
strBuffer.AppendF($"M{row+1}{col+1}:{((float*)&this)[row+col*4]}\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
291
BeefLibs/Beefy2D/src/geom/Plane.bf
Normal file
291
BeefLibs/Beefy2D/src/geom/Plane.bf
Normal file
|
@ -0,0 +1,291 @@
|
|||
// This file contains portions of code from the FNA project (github.com/FNA-XNA/FNA),
|
||||
// released under the Microsoft Public License
|
||||
|
||||
using System;
|
||||
|
||||
namespace Beefy.geom
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the intersection between a <see cref="Plane"/> and a bounding volume.
|
||||
/// </summary>
|
||||
public enum PlaneIntersectionType
|
||||
{
|
||||
/// <summary>
|
||||
/// There is no intersection, the bounding volume is in the negative half space of the plane.
|
||||
/// </summary>
|
||||
Front,
|
||||
/// <summary>
|
||||
/// There is no intersection, the bounding volume is in the positive half space of the plane.
|
||||
/// </summary>
|
||||
Back,
|
||||
/// <summary>
|
||||
/// The plane is intersected.
|
||||
/// </summary>
|
||||
Intersecting
|
||||
}
|
||||
|
||||
public struct Plane
|
||||
{
|
||||
public Vector3 Normal;
|
||||
public float D;
|
||||
|
||||
public this(Vector4 value)
|
||||
: this(Vector3(value.mX, value.mY, value.mZ), value.mW)
|
||||
{
|
||||
}
|
||||
|
||||
public this(Vector3 normal, float d)
|
||||
{
|
||||
Normal = normal;
|
||||
D = d;
|
||||
}
|
||||
|
||||
public this(Vector3 a, Vector3 b, Vector3 c)
|
||||
{
|
||||
Vector3 ab = b - a;
|
||||
Vector3 ac = c - a;
|
||||
|
||||
Vector3 cross = Vector3.Cross(ab, ac);
|
||||
Vector3.Normalize(cross, out Normal);
|
||||
D = -(Vector3.Dot(Normal, a));
|
||||
}
|
||||
|
||||
public this(float a, float b, float c, float d)
|
||||
: this(Vector3(a, b, c), d)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public float Dot(Vector4 value)
|
||||
{
|
||||
return (
|
||||
(this.Normal.mX * value.mX) +
|
||||
(this.Normal.mY * value.mY) +
|
||||
(this.Normal.mZ * value.mZ) +
|
||||
(this.D * value.mW)
|
||||
);
|
||||
}
|
||||
|
||||
public void Dot(ref Vector4 value, out float result)
|
||||
{
|
||||
result = (
|
||||
(this.Normal.mX * value.mX) +
|
||||
(this.Normal.mY * value.mY) +
|
||||
(this.Normal.mZ * value.mZ) +
|
||||
(this.D * value.mW)
|
||||
);
|
||||
}
|
||||
|
||||
public float DotCoordinate(Vector3 value)
|
||||
{
|
||||
return (
|
||||
(this.Normal.mX * value.mX) +
|
||||
(this.Normal.mY * value.mY) +
|
||||
(this.Normal.mZ * value.mZ) +
|
||||
this.D
|
||||
);
|
||||
}
|
||||
|
||||
public void DotCoordinate(ref Vector3 value, out float result)
|
||||
{
|
||||
result = (
|
||||
(this.Normal.mX * value.mX) +
|
||||
(this.Normal.mY * value.mY) +
|
||||
(this.Normal.mZ * value.mZ) +
|
||||
this.D
|
||||
);
|
||||
}
|
||||
|
||||
public float DotNormal(Vector3 value)
|
||||
{
|
||||
return (
|
||||
(this.Normal.mX * value.mX) +
|
||||
(this.Normal.mY * value.mY) +
|
||||
(this.Normal.mZ * value.mZ)
|
||||
);
|
||||
}
|
||||
|
||||
public void DotNormal(Vector3 value, out float result)
|
||||
{
|
||||
result = (
|
||||
(this.Normal.mX * value.mX) +
|
||||
(this.Normal.mY * value.mY) +
|
||||
(this.Normal.mZ * value.mZ)
|
||||
);
|
||||
}
|
||||
|
||||
public void Normalize() mut
|
||||
{
|
||||
float length = Normal.Length;
|
||||
float factor = 1.0f / length;
|
||||
Normal = Vector3.Multiply(Normal, factor);
|
||||
D = D * factor;
|
||||
}
|
||||
|
||||
/*public PlaneIntersectionType Intersects(BoundingBox box)
|
||||
{
|
||||
return box.Intersects(this);
|
||||
}
|
||||
|
||||
public void Intersects(ref BoundingBox box, out PlaneIntersectionType result)
|
||||
{
|
||||
box.Intersects(ref this, out result);
|
||||
}
|
||||
|
||||
public PlaneIntersectionType Intersects(BoundingSphere sphere)
|
||||
{
|
||||
return sphere.Intersects(this);
|
||||
}
|
||||
|
||||
public void Intersects(ref BoundingSphere sphere, out PlaneIntersectionType result)
|
||||
{
|
||||
sphere.Intersects(ref this, out result);
|
||||
}
|
||||
|
||||
public PlaneIntersectionType Intersects(BoundingFrustum frustum)
|
||||
{
|
||||
return frustum.Intersects(this);
|
||||
}*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region Internal Methods
|
||||
|
||||
internal PlaneIntersectionType Intersects(ref Vector3 point)
|
||||
{
|
||||
float distance;
|
||||
DotCoordinate(ref point, out distance);
|
||||
if (distance > 0)
|
||||
{
|
||||
return PlaneIntersectionType.Front;
|
||||
}
|
||||
if (distance < 0)
|
||||
{
|
||||
return PlaneIntersectionType.Back;
|
||||
}
|
||||
return PlaneIntersectionType.Intersecting;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Static Methods
|
||||
|
||||
public static Plane Normalize(Plane value)
|
||||
{
|
||||
Plane ret;
|
||||
Normalize(value, out ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void Normalize(Plane value, out Plane result)
|
||||
{
|
||||
float length = value.Normal.Length;
|
||||
float factor = 1.0f / length;
|
||||
result.Normal = Vector3.Multiply(value.Normal, factor);
|
||||
result.D = value.D * factor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms a normalized plane by a matrix.
|
||||
/// </summary>
|
||||
/// <param name="plane">The normalized plane to transform.</param>
|
||||
/// <param name="matrix">The transformation matrix.</param>
|
||||
/// <returns>The transformed plane.</returns>
|
||||
public static Plane Transform(Plane plane, Matrix4 matrix)
|
||||
{
|
||||
Plane result;
|
||||
Transform(plane, matrix, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms a normalized plane by a matrix.
|
||||
/// </summary>
|
||||
/// <param name="plane">The normalized plane to transform.</param>
|
||||
/// <param name="matrix">The transformation matrix.</param>
|
||||
/// <param name="result">The transformed plane.</param>
|
||||
public static void Transform(
|
||||
Plane plane,
|
||||
Matrix4 matrix,
|
||||
out Plane result
|
||||
) {
|
||||
/* See "Transforming Normals" in
|
||||
* http://www.glprogramming.com/red/appendixf.html
|
||||
* for an explanation of how this works.
|
||||
*/
|
||||
Matrix4 transformedMatrix;
|
||||
transformedMatrix = Matrix4.Invert(matrix);
|
||||
transformedMatrix = Matrix4.Transpose(transformedMatrix);
|
||||
Vector4 vector = Vector4(plane.Normal, plane.D);
|
||||
Vector4 transformedVector;
|
||||
Vector4.Transform(
|
||||
vector,
|
||||
transformedMatrix,
|
||||
out transformedVector
|
||||
);
|
||||
result = Plane(transformedVector);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms a normalized plane by a quaternion rotation.
|
||||
/// </summary>
|
||||
/// <param name="plane">The normalized plane to transform.</param>
|
||||
/// <param name="rotation">The quaternion rotation.</param>
|
||||
/// <returns>The transformed plane.</returns>
|
||||
public static Plane Transform(Plane plane, Quaternion rotation)
|
||||
{
|
||||
Plane result;
|
||||
Transform(plane, rotation, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms a normalized plane by a quaternion rotation.
|
||||
/// </summary>
|
||||
/// <param name="plane">The normalized plane to transform.</param>
|
||||
/// <param name="rotation">The quaternion rotation.</param>
|
||||
/// <param name="result">The transformed plane.</param>
|
||||
public static void Transform(
|
||||
Plane plane,
|
||||
Quaternion rotation,
|
||||
out Plane result
|
||||
) {
|
||||
result.Normal = Vector3.Transform(
|
||||
plane.Normal,
|
||||
rotation
|
||||
);
|
||||
result.D = plane.D;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Static Operators and Override Methods
|
||||
|
||||
public static bool operator !=(Plane plane1, Plane plane2)
|
||||
{
|
||||
return !plane1.Equals(plane2);
|
||||
}
|
||||
|
||||
public static bool operator ==(Plane plane1, Plane plane2)
|
||||
{
|
||||
return plane1.Equals(plane2);
|
||||
}
|
||||
|
||||
public bool Equals(Plane other)
|
||||
{
|
||||
return (Normal == other.Normal && D == other.D);
|
||||
}
|
||||
|
||||
public int GetHashCode()
|
||||
{
|
||||
return Normal.GetHashCode() ^ D.GetHashCode();
|
||||
}
|
||||
|
||||
public override void ToString(String str)
|
||||
{
|
||||
str.AppendF($"{Normal:{Normal} D:{D}}");
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,3 +1,6 @@
|
|||
// This file contains portions of code from the FNA project (github.com/FNA-XNA/FNA),
|
||||
// released under the Microsoft Public License
|
||||
|
||||
using System;
|
||||
using Beefy.gfx;
|
||||
|
||||
|
@ -189,43 +192,50 @@ namespace Beefy.geom
|
|||
|
||||
public static void CreateFromRotationMatrix(ref Matrix4 matrix, out Quaternion result)
|
||||
{
|
||||
float num8 = (matrix.m11 + matrix.m22) + matrix.m33;
|
||||
if (num8 > 0f)
|
||||
{
|
||||
float num = (float)Math.Sqrt((double)(num8 + 1f));
|
||||
result.mW = num * 0.5f;
|
||||
num = 0.5f / num;
|
||||
result.mX = (matrix.m23 - matrix.m32) * num;
|
||||
result.mY = (matrix.m31 - matrix.m13) * num;
|
||||
result.mZ = (matrix.m12 - matrix.m21) * num;
|
||||
}
|
||||
else if ((matrix.m11 >= matrix.m22) && (matrix.m11 >= matrix.m33))
|
||||
{
|
||||
float num7 = (float)Math.Sqrt((double)(((1f + matrix.m11) - matrix.m22) - matrix.m33));
|
||||
float num4 = 0.5f / num7;
|
||||
result.mX = 0.5f * num7;
|
||||
result.mY = (matrix.m12 + matrix.m21) * num4;
|
||||
result.mZ = (matrix.m13 + matrix.m31) * num4;
|
||||
result.mW = (matrix.m23 - matrix.m32) * num4;
|
||||
}
|
||||
else if (matrix.m22 > matrix.m33)
|
||||
{
|
||||
float num6 = (float)Math.Sqrt((double)(((1f + matrix.m22) - matrix.m11) - matrix.m33));
|
||||
float num3 = 0.5f / num6;
|
||||
result.mX = (matrix.m21 + matrix.m12) * num3;
|
||||
result.mY = 0.5f * num6;
|
||||
result.mZ = (matrix.m32 + matrix.m23) * num3;
|
||||
result.mW = (matrix.m31 - matrix.m13) * num3;
|
||||
}
|
||||
else
|
||||
{
|
||||
float num5 = (float)Math.Sqrt((double)(((1f + matrix.m33) - matrix.m11) - matrix.m22));
|
||||
float num2 = 0.5f / num5;
|
||||
result.mX = (matrix.m31 + matrix.m13) * num2;
|
||||
result.mY = (matrix.m32 + matrix.m23) * num2;
|
||||
result.mZ = 0.5f * num5;
|
||||
result.mW = (matrix.m12 - matrix.m21) * num2;
|
||||
}
|
||||
float sqrt;
|
||||
float half;
|
||||
float scale = matrix.m00 + matrix.m11 + matrix.m22;
|
||||
|
||||
if (scale > 0.0f)
|
||||
{
|
||||
sqrt = (float) Math.Sqrt(scale + 1.0f);
|
||||
result.mW = sqrt * 0.5f;
|
||||
sqrt = 0.5f / sqrt;
|
||||
|
||||
result.mX = (matrix.m21 - matrix.m12) * sqrt;
|
||||
result.mY = (matrix.m02 - matrix.m20) * sqrt;
|
||||
result.mZ = (matrix.m10 - matrix.m01) * sqrt;
|
||||
}
|
||||
else if ((matrix.m00 >= matrix.m11) && (matrix.m00 >= matrix.m22))
|
||||
{
|
||||
sqrt = (float) Math.Sqrt(1.0f + matrix.m00 - matrix.m11 - matrix.m22);
|
||||
half = 0.5f / sqrt;
|
||||
|
||||
result.mX = 0.5f * sqrt;
|
||||
result.mY = (matrix.m10 + matrix.m01) * half;
|
||||
result.mZ = (matrix.m20 + matrix.m02) * half;
|
||||
result.mW = (matrix.m21 - matrix.m12) * half;
|
||||
}
|
||||
else if (matrix.m11 > matrix.m22)
|
||||
{
|
||||
sqrt = (float) Math.Sqrt(1.0f + matrix.m11 - matrix.m00 - matrix.m22);
|
||||
half = 0.5f/sqrt;
|
||||
|
||||
result.mX = (matrix.m01 + matrix.m10)*half;
|
||||
result.mY = 0.5f*sqrt;
|
||||
result.mZ = (matrix.m12 + matrix.m21)*half;
|
||||
result.mW = (matrix.m02 - matrix.m20)*half;
|
||||
}
|
||||
else
|
||||
{
|
||||
sqrt = (float) Math.Sqrt(1.0f + matrix.m22 - matrix.m00 - matrix.m11);
|
||||
half = 0.5f / sqrt;
|
||||
|
||||
result.mX = (matrix.m02 + matrix.m20) * half;
|
||||
result.mY = (matrix.m12 + matrix.m21) * half;
|
||||
result.mZ = 0.5f * sqrt;
|
||||
result.mW = (matrix.m10 - matrix.m01) * half;
|
||||
}
|
||||
}
|
||||
|
||||
public static Quaternion CreateFromYawPitchRoll(float yaw, float pitch, float roll)
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// This file contains portions of code from the FNA project (github.com/FNA-XNA/FNA),
|
||||
// released under the Microsoft Public License
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Text;
|
||||
|
@ -131,7 +134,7 @@ namespace Beefy.geom
|
|||
{
|
||||
Vector3 newVec;
|
||||
Normalize(vector, out newVec);
|
||||
return vector;
|
||||
return newVec;
|
||||
}
|
||||
|
||||
public static void Normalize(Vector3 value, out Vector3 result)
|
||||
|
@ -173,7 +176,7 @@ namespace Beefy.geom
|
|||
return new Vector2D((float)Math.Cos(angle) * length, (float)Math.Sin(angle) * length);
|
||||
}*/
|
||||
|
||||
public static Vector3 Transform(Vector3 vec, Matrix4 matrix)
|
||||
public static Vector3 TransformW(Vector3 vec, Matrix4 matrix)
|
||||
{
|
||||
Vector3 result;
|
||||
float fInvW = 1.0f / (matrix.m30 * vec.mX + matrix.m31 * vec.mY + matrix.m32 * vec.mZ + matrix.m33);
|
||||
|
@ -181,9 +184,19 @@ namespace Beefy.geom
|
|||
result.mX = (matrix.m00 * vec.mX + matrix.m01 * vec.mY + matrix.m02 * vec.mZ + matrix.m03) * fInvW;
|
||||
result.mY = (matrix.m10 * vec.mX + matrix.m11 * vec.mY + matrix.m12 * vec.mZ + matrix.m13) * fInvW;
|
||||
result.mZ = (matrix.m20 * vec.mX + matrix.m21 * vec.mY + matrix.m22 * vec.mZ + matrix.m23) * fInvW;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Vector3 Transform(Vector3 vec, Matrix4 matrix)
|
||||
{
|
||||
Vector3 result;
|
||||
result.mX = (vec.mX * matrix.m00) + (vec.mY * matrix.m01) + (vec.mZ * matrix.m02) + matrix.m03;
|
||||
result.mY = (vec.mX * matrix.m10) + (vec.mY * matrix.m11) + (vec.mZ * matrix.m12) + matrix.m13;
|
||||
result.mZ = (vec.mX * matrix.m20) + (vec.mY * matrix.m21) + (vec.mZ * matrix.m22) + matrix.m23;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*public static void Transform(Vector3[] sourceArray, ref Matrix4 matrix, Vector3[] destinationArray)
|
||||
{
|
||||
//Debug.Assert(destinationArray.Length >= sourceArray.Length, "The destination array is smaller than the source array.");
|
||||
|
@ -199,6 +212,51 @@ namespace Beefy.geom
|
|||
}
|
||||
}*/
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see>Vector3</see> pointing in the opposite
|
||||
/// direction of <paramref name="value"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to negate.</param>
|
||||
/// <returns>The vector negation of <paramref name="value"/>.</returns>
|
||||
public static Vector3 Negate(Vector3 value)
|
||||
{
|
||||
return .(-value.mX, -value.mY, -value.mZ);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores a <see>Vector3</see> pointing in the opposite
|
||||
/// direction of <paramref name="value"/> in <paramref name="result"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to negate.</param>
|
||||
/// <param name="result">The vector that the negation of <paramref name="value"/> will be stored in.</param>
|
||||
public static void Negate(Vector3 value, out Vector3 result)
|
||||
{
|
||||
result.mX = -value.mX;
|
||||
result.mY = -value.mY;
|
||||
result.mZ = -value.mZ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="Vector3"/> that contains a multiplication of two vectors.
|
||||
/// </summary>
|
||||
/// <param name="value1">Source <see cref="Vector3"/>.</param>
|
||||
/// <param name="value2">Source <see cref="Vector3"/>.</param>
|
||||
/// <returns>The result of the vector multiplication.</returns>
|
||||
public static Vector3 Multiply(Vector3 value1, Vector3 value2)
|
||||
{
|
||||
return .(value1.mX * value2.mX, value1.mY * value2.mY, value1.mZ * value2.mZ);
|
||||
}
|
||||
|
||||
public static Vector3 Multiply(Vector3 value1, float value2)
|
||||
{
|
||||
return .(value1.mX * value2, value1.mY * value2, value1.mZ * value2);
|
||||
}
|
||||
|
||||
public void Normalize() mut
|
||||
{
|
||||
Normalize(this, out this);
|
||||
}
|
||||
|
||||
public static Vector3 Transform(Vector3 vec, Quaternion quat)
|
||||
{
|
||||
Matrix4 matrix = quat.ToMatrix();
|
||||
|
@ -234,6 +292,11 @@ namespace Beefy.geom
|
|||
return Vector3(vec1.mX - vec2.mX, vec1.mY - vec2.mY, vec1.mZ - vec2.mZ);
|
||||
}
|
||||
|
||||
public static Vector3 operator -(Vector3 vec1)
|
||||
{
|
||||
return Vector3(-vec1.mX, -vec1.mY, -vec1.mZ);
|
||||
}
|
||||
|
||||
public static Vector3 operator *(Vector3 vec, float scale)
|
||||
{
|
||||
return Vector3(vec.mX * scale, vec.mY * scale, vec.mZ * scale);
|
||||
|
|
1435
BeefLibs/Beefy2D/src/geom/Vector4.bf
Normal file
1435
BeefLibs/Beefy2D/src/geom/Vector4.bf
Normal file
File diff suppressed because it is too large
Load diff
59
BeefLibs/Beefy2D/src/geom/Viewport.bf
Normal file
59
BeefLibs/Beefy2D/src/geom/Viewport.bf
Normal file
|
@ -0,0 +1,59 @@
|
|||
// This file contains portions of code from the FNA project (github.com/FNA-XNA/FNA),
|
||||
// released under the Microsoft Public License
|
||||
|
||||
using Beefy.geom;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Beefy.geom
|
||||
{
|
||||
struct Viewport
|
||||
{
|
||||
private int mX;
|
||||
private int mY;
|
||||
private int mWidth;
|
||||
private int mHeight;
|
||||
private float mMinDepth;
|
||||
private float mMaxDepth;
|
||||
|
||||
public this(int x, int y, int width, int height,float minDepth,float maxDepth)
|
||||
{
|
||||
this.mX = x;
|
||||
this.mY = y;
|
||||
this.mWidth = width;
|
||||
this.mHeight = height;
|
||||
this.mMinDepth = minDepth;
|
||||
this.mMaxDepth = maxDepth;
|
||||
}
|
||||
|
||||
/// Unprojects a Vector3 from screen space into world space.
|
||||
/// @param source The Vector3 to unproject.
|
||||
/// @param projection The projection
|
||||
/// @param view The view
|
||||
/// @param world The world
|
||||
public Vector3 Unproject(Vector3 source, Matrix4 projection, Matrix4 view, Matrix4 world)
|
||||
{
|
||||
var source;
|
||||
|
||||
Matrix4 matrix = Matrix4.Invert(Matrix4.Multiply(Matrix4.Multiply(world, view), projection));
|
||||
source.mX = (((source.mX - this.mX) / ((float) this.mWidth)) * 2f) - 1f;
|
||||
source.mY = -((((source.mY - this.mY) / ((float) this.mHeight)) * 2f) - 1f);
|
||||
source.mZ = (source.mZ - this.mMinDepth) / (this.mMaxDepth - this.mMinDepth);
|
||||
Vector3 vector = Vector3.Transform(source, matrix);
|
||||
float a = (((source.mX * matrix.m30) + (source.mY * matrix.m31)) + (source.mZ * matrix.m32)) + matrix.m33;
|
||||
if (!WithinEpsilon(a, 1f))
|
||||
{
|
||||
vector.mX = vector.mX / a;
|
||||
vector.mY = vector.mY / a;
|
||||
vector.mZ = vector.mZ / a;
|
||||
}
|
||||
return vector;
|
||||
|
||||
}
|
||||
|
||||
private static bool WithinEpsilon(float a, float b)
|
||||
{
|
||||
float num = a - b;
|
||||
return ((-1.401298E-45f <= num) && (num <= float.Epsilon));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -442,7 +442,10 @@ namespace Beefy.gfx
|
|||
//static unsafe extern void Gfx_DrawIndexedVertices2D(void* vtxData, int vtxCount, int* idxData, int idxCount, float a, float b, float c, float d, float tx, float ty, float z);
|
||||
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
static extern void Gfx_DrawIndexedVertices2D(int32 vertexSize, void* vtxData, int32 vtxCount, uint16* idxData, int32 idxCount, float a, float b, float c, float d, float tx, float ty, float z);
|
||||
static extern void Gfx_DrawIndexedVertices(int32 vertexSize, void* vtxData, int32 vtxCount, uint16* idxData, int32 idxCount);
|
||||
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
static extern void Gfx_DrawIndexedVertices2D(int32 vertexSize, void* vtxData, int32 vtxCount, uint16* idxData, int32 idxCount, float a, float b, float c, float d, float tx, float ty, float z);
|
||||
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
static extern void Gfx_SetShaderConstantData(int32 usageIdx, int32 slotIdx, void* data, int32 size);
|
||||
|
@ -794,14 +797,28 @@ namespace Beefy.gfx
|
|||
|
||||
public void DrawIndexedVertices(VertexDefinition vertexDef, void* vertices, int vtxCount, uint16[] indices)
|
||||
{
|
||||
Gfx_DrawIndexedVertices2D(vertexDef.mVertexSize, vertices, (int32)vtxCount, indices.CArray(), (int32)indices.Count,
|
||||
mMatrix.a, mMatrix.b, mMatrix.c, mMatrix.d, mMatrix.tx, mMatrix.ty, ZDepth);
|
||||
if (vertexDef.mPosition2DOffset != -1)
|
||||
{
|
||||
Gfx_DrawIndexedVertices2D(vertexDef.mVertexSize, vertices, (int32)vtxCount, indices.CArray(), (int32)indices.Count,
|
||||
mMatrix.a, mMatrix.b, mMatrix.c, mMatrix.d, mMatrix.tx, mMatrix.ty, ZDepth);
|
||||
}
|
||||
else
|
||||
{
|
||||
Gfx_DrawIndexedVertices(vertexDef.mVertexSize, vertices, (int32)vtxCount, indices.CArray(), (int32)indices.Count);
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawIndexedVertices(VertexDefinition vertexDef, void* vertices, int vtxCount, uint16* indices, int idxCount)
|
||||
{
|
||||
Gfx_DrawIndexedVertices2D(vertexDef.mVertexSize, vertices, (int32)vtxCount, indices, (int32)idxCount,
|
||||
mMatrix.a, mMatrix.b, mMatrix.c, mMatrix.d, mMatrix.tx, mMatrix.ty, ZDepth);
|
||||
if (vertexDef.mPosition2DOffset != -1)
|
||||
{
|
||||
Gfx_DrawIndexedVertices2D(vertexDef.mVertexSize, vertices, (int32)vtxCount, indices, (int32)idxCount,
|
||||
mMatrix.a, mMatrix.b, mMatrix.c, mMatrix.d, mMatrix.tx, mMatrix.ty, ZDepth);
|
||||
}
|
||||
else
|
||||
{
|
||||
Gfx_DrawIndexedVertices(vertexDef.mVertexSize, vertices, (int32)vtxCount, indices, (int32)idxCount);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetVertexShaderConstantData(int slotIdx, void* data, int size)
|
||||
|
|
|
@ -48,7 +48,13 @@ namespace Beefy.gfx
|
|||
|
||||
#if !STUDIO_CLIENT
|
||||
extension ModelDef
|
||||
{
|
||||
{
|
||||
public enum ModelCreateFlags
|
||||
{
|
||||
None = 0,
|
||||
NoSetRenderState = 1
|
||||
}
|
||||
|
||||
public class Animation
|
||||
{
|
||||
public void* mNativeModelDefAnimation;
|
||||
|
@ -103,11 +109,20 @@ namespace Beefy.gfx
|
|||
extern static void* Res_OpenModel(char8* fileName, char8* baseDir, void* nativeVertexDef);
|
||||
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
extern static void* ModelDef_CreateModelInstance(void* nativeModel);
|
||||
extern static void* ModelDef_CreateModelInstance(void* nativeModel, ModelCreateFlags flags);
|
||||
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
extern static void ModelDef_Compact(void* nativeModel);
|
||||
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
extern static void ModelDef_SetBaseDir(void* nativeModel, char8* baseDir);
|
||||
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
extern static char8* ModelDef_GetInfo(void* nativeModel);
|
||||
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
extern static void ModelDef_GetBounds(void* nativeModel, out Vector3 min, out Vector3 max);
|
||||
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
extern static float ModelDef_GetFrameRate(void* nativeModel);
|
||||
|
||||
|
@ -123,6 +138,9 @@ namespace Beefy.gfx
|
|||
[CallingConvention(.Stdcall), CLink]
|
||||
extern static void ModelDef_SetTextures(void* nativeModel, int32 meshIdx, int32 primitivesIdx, char8** paths, int32 pathCount);
|
||||
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
extern static bool ModelDef_RayIntersect(void* nativeModel, Matrix4 worldMtx, Vector3 origin, Vector3 vec, out Vector3 outIntersect, out float outDistance);
|
||||
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
extern static Span<uint8> Res_SerializeModel(void* nativeModel);
|
||||
|
||||
|
@ -147,20 +165,20 @@ namespace Beefy.gfx
|
|||
public static ModelDef LoadModel(String fileName, String baseDir)
|
||||
{
|
||||
void* nativeModelDef = null;
|
||||
if (fileName.EndsWith(".bfm", .OrdinalIgnoreCase))
|
||||
nativeModelDef = Res_OpenModel(fileName, baseDir, VertexDef.sVertexDefinition.mNativeVertexDefinition);
|
||||
if (fileName.EndsWith(".gltf", .OrdinalIgnoreCase))
|
||||
nativeModelDef = Res_OpenGLTF(fileName, baseDir, VertexDef.sVertexDefinition.mNativeVertexDefinition);
|
||||
else if (fileName.EndsWith(".fbx", .OrdinalIgnoreCase))
|
||||
nativeModelDef = Res_OpenFBX(fileName, VertexDef.sVertexDefinition.mNativeVertexDefinition);
|
||||
else
|
||||
nativeModelDef = Res_OpenGLTF(fileName, baseDir, VertexDef.sVertexDefinition.mNativeVertexDefinition);
|
||||
nativeModelDef = Res_OpenModel(fileName, baseDir, VertexDef.sVertexDefinition.mNativeVertexDefinition);
|
||||
if (nativeModelDef == null)
|
||||
return null;
|
||||
return new ModelDef(nativeModelDef);
|
||||
}
|
||||
|
||||
public ModelInstance CreateInstance()
|
||||
public ModelInstance CreateInstance(ModelCreateFlags flags = .None)
|
||||
{
|
||||
void* nativeModelInstance = ModelDef_CreateModelInstance(mNativeModelDef);
|
||||
void* nativeModelInstance = ModelDef_CreateModelInstance(mNativeModelDef, flags);
|
||||
if (nativeModelInstance == null)
|
||||
return null;
|
||||
var modelInstance = new ModelInstance(nativeModelInstance, this);
|
||||
|
@ -177,6 +195,21 @@ namespace Beefy.gfx
|
|||
str.Append(ModelDef_GetInfo(mNativeModelDef));
|
||||
}
|
||||
|
||||
public void GetBounds(out Vector3 min, out Vector3 max)
|
||||
{
|
||||
ModelDef_GetBounds(mNativeModelDef, out min, out max);
|
||||
}
|
||||
|
||||
public void Compact()
|
||||
{
|
||||
ModelDef_Compact(mNativeModelDef);
|
||||
}
|
||||
|
||||
public void SetBaseDir(StringView baseDir)
|
||||
{
|
||||
ModelDef_SetBaseDir(mNativeModelDef, baseDir.ToScopeCStr!());
|
||||
}
|
||||
|
||||
public void SetTextures(int meshIdx, int primitivesIdx, Span<char8*> paths)
|
||||
{
|
||||
ModelDef_SetTextures(mNativeModelDef, (.)meshIdx, (.)primitivesIdx, paths.Ptr, (.)paths.Length);
|
||||
|
@ -187,6 +220,11 @@ namespace Beefy.gfx
|
|||
var span = Res_SerializeModel(mNativeModelDef);
|
||||
data.AddRange(span);
|
||||
}
|
||||
|
||||
public bool RayIntersect(Matrix4 worldMtx, Vector3 origin, Vector3 vec, out Vector3 outIntersect, out float outDistance)
|
||||
{
|
||||
return ModelDef_RayIntersect(mNativeModelDef, worldMtx, origin, vec, out outIntersect, out outDistance);
|
||||
}
|
||||
}
|
||||
|
||||
public class ModelInstance : RenderCmd
|
||||
|
|
|
@ -19,6 +19,12 @@ namespace Beefy.gfx
|
|||
Always
|
||||
}
|
||||
|
||||
public enum Topology
|
||||
{
|
||||
TriangleList,
|
||||
LineList
|
||||
}
|
||||
|
||||
#if !STUDIO_CLIENT
|
||||
public class RenderState
|
||||
{
|
||||
|
@ -34,6 +40,9 @@ namespace Beefy.gfx
|
|||
[CallingConvention(.Stdcall), CLink]
|
||||
static extern void RenderState_SetTexWrap(void* renderState, bool texWrap);
|
||||
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
static extern void RenderState_SetWireframe(void* renderState, bool wireframe);
|
||||
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
static extern void RenderState_DisableClip(void* renderState);
|
||||
|
||||
|
@ -46,6 +55,9 @@ namespace Beefy.gfx
|
|||
[CallingConvention(.Stdcall), CLink]
|
||||
static extern void RenderState_SetDepthWrite(void* nativeRenderState, int32 depthWrite);
|
||||
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
static extern void RenderState_SetTopology(void* nativeRenderState, int32 topology);
|
||||
|
||||
public void* mNativeRenderState;
|
||||
public bool mIsFromDefaultRenderState;
|
||||
|
||||
|
@ -115,6 +127,22 @@ namespace Beefy.gfx
|
|||
RenderState_SetTexWrap(mNativeRenderState, value);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Wireframe
|
||||
{
|
||||
set
|
||||
{
|
||||
RenderState_SetWireframe(mNativeRenderState, value);
|
||||
}
|
||||
}
|
||||
|
||||
public Topology Topology
|
||||
{
|
||||
set
|
||||
{
|
||||
RenderState_SetTopology(mNativeRenderState, (.)value);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
public class RenderState
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue