This commit is contained in:
2025-05-13 03:08:33 +03:00
parent f06ea6c9f0
commit 6e30658119
101 changed files with 12402 additions and 0 deletions
@@ -0,0 +1,89 @@
namespace SourceFormatParser.Common
{
/// <summary>
/// mathlib/color_conversion.cpp. Not full ofc.
/// </summary>
public static class ColorConversion
{
// This is aligned to 16-byte boundaries so that we can load it
// onto SIMD registers easily if needed (used by SSE version of lightmaps)
// TODO: move this into the one DLL that actually uses it, instead of statically
// linking it everywhere via mathlib.
private static float[] power2_n = new float[256] // 2**(index - 128) / 255
{
1.152445441982634800E-041f, 2.304890883965269600E-041f, 4.609781767930539200E-041f, 9.219563535861078400E-041f,
1.843912707172215700E-040f, 3.687825414344431300E-040f, 7.375650828688862700E-040f, 1.475130165737772500E-039f,
2.950260331475545100E-039f, 5.900520662951090200E-039f, 1.180104132590218000E-038f, 2.360208265180436100E-038f,
4.720416530360872100E-038f, 9.440833060721744200E-038f, 1.888166612144348800E-037f, 3.776333224288697700E-037f,
7.552666448577395400E-037f, 1.510533289715479100E-036f, 3.021066579430958200E-036f, 6.042133158861916300E-036f,
1.208426631772383300E-035f, 2.416853263544766500E-035f, 4.833706527089533100E-035f, 9.667413054179066100E-035f,
1.933482610835813200E-034f, 3.866965221671626400E-034f, 7.733930443343252900E-034f, 1.546786088668650600E-033f,
3.093572177337301200E-033f, 6.187144354674602300E-033f, 1.237428870934920500E-032f, 2.474857741869840900E-032f,
4.949715483739681800E-032f, 9.899430967479363700E-032f, 1.979886193495872700E-031f, 3.959772386991745500E-031f,
7.919544773983491000E-031f, 1.583908954796698200E-030f, 3.167817909593396400E-030f, 6.335635819186792800E-030f,
1.267127163837358600E-029f, 2.534254327674717100E-029f, 5.068508655349434200E-029f, 1.013701731069886800E-028f,
2.027403462139773700E-028f, 4.054806924279547400E-028f, 8.109613848559094700E-028f, 1.621922769711818900E-027f,
3.243845539423637900E-027f, 6.487691078847275800E-027f, 1.297538215769455200E-026f, 2.595076431538910300E-026f,
5.190152863077820600E-026f, 1.038030572615564100E-025f, 2.076061145231128300E-025f, 4.152122290462256500E-025f,
8.304244580924513000E-025f, 1.660848916184902600E-024f, 3.321697832369805200E-024f, 6.643395664739610400E-024f,
1.328679132947922100E-023f, 2.657358265895844200E-023f, 5.314716531791688300E-023f, 1.062943306358337700E-022f,
2.125886612716675300E-022f, 4.251773225433350700E-022f, 8.503546450866701300E-022f, 1.700709290173340300E-021f,
3.401418580346680500E-021f, 6.802837160693361100E-021f, 1.360567432138672200E-020f, 2.721134864277344400E-020f,
5.442269728554688800E-020f, 1.088453945710937800E-019f, 2.176907891421875500E-019f, 4.353815782843751100E-019f,
8.707631565687502200E-019f, 1.741526313137500400E-018f, 3.483052626275000900E-018f, 6.966105252550001700E-018f,
1.393221050510000300E-017f, 2.786442101020000700E-017f, 5.572884202040001400E-017f, 1.114576840408000300E-016f,
2.229153680816000600E-016f, 4.458307361632001100E-016f, 8.916614723264002200E-016f, 1.783322944652800400E-015f,
3.566645889305600900E-015f, 7.133291778611201800E-015f, 1.426658355722240400E-014f, 2.853316711444480700E-014f,
5.706633422888961400E-014f, 1.141326684577792300E-013f, 2.282653369155584600E-013f, 4.565306738311169100E-013f,
9.130613476622338300E-013f, 1.826122695324467700E-012f, 3.652245390648935300E-012f, 7.304490781297870600E-012f,
1.460898156259574100E-011f, 2.921796312519148200E-011f, 5.843592625038296500E-011f, 1.168718525007659300E-010f,
2.337437050015318600E-010f, 4.674874100030637200E-010f, 9.349748200061274400E-010f, 1.869949640012254900E-009f,
3.739899280024509800E-009f, 7.479798560049019500E-009f, 1.495959712009803900E-008f, 2.991919424019607800E-008f,
5.983838848039215600E-008f, 1.196767769607843100E-007f, 2.393535539215686200E-007f, 4.787071078431372500E-007f,
9.574142156862745000E-007f, 1.914828431372549000E-006f, 3.829656862745098000E-006f, 7.659313725490196000E-006f,
1.531862745098039200E-005f, 3.063725490196078400E-005f, 6.127450980392156800E-005f, 1.225490196078431400E-004f,
2.450980392156862700E-004f, 4.901960784313725400E-004f, 9.803921568627450800E-004f, 1.960784313725490200E-003f,
3.921568627450980300E-003f, 7.843137254901960700E-003f, 1.568627450980392100E-002f, 3.137254901960784300E-002f,
6.274509803921568500E-002f, 1.254901960784313700E-001f, 2.509803921568627400E-001f, 5.019607843137254800E-001f,
1.003921568627451000E+000f, 2.007843137254901900E+000f, 4.015686274509803900E+000f, 8.031372549019607700E+000f,
1.606274509803921500E+001f, 3.212549019607843100E+001f, 6.425098039215686200E+001f, 1.285019607843137200E+002f,
2.570039215686274500E+002f, 5.140078431372548900E+002f, 1.028015686274509800E+003f, 2.056031372549019600E+003f,
4.112062745098039200E+003f, 8.224125490196078300E+003f, 1.644825098039215700E+004f, 3.289650196078431300E+004f,
6.579300392156862700E+004f, 1.315860078431372500E+005f, 2.631720156862745100E+005f, 5.263440313725490100E+005f,
1.052688062745098000E+006f, 2.105376125490196000E+006f, 4.210752250980392100E+006f, 8.421504501960784200E+006f,
1.684300900392156800E+007f, 3.368601800784313700E+007f, 6.737203601568627400E+007f, 1.347440720313725500E+008f,
2.694881440627450900E+008f, 5.389762881254901900E+008f, 1.077952576250980400E+009f, 2.155905152501960800E+009f,
4.311810305003921500E+009f, 8.623620610007843000E+009f, 1.724724122001568600E+010f, 3.449448244003137200E+010f,
6.898896488006274400E+010f, 1.379779297601254900E+011f, 2.759558595202509800E+011f, 5.519117190405019500E+011f,
1.103823438081003900E+012f, 2.207646876162007800E+012f, 4.415293752324015600E+012f, 8.830587504648031200E+012f,
1.766117500929606200E+013f, 3.532235001859212500E+013f, 7.064470003718425000E+013f, 1.412894000743685000E+014f,
2.825788001487370000E+014f, 5.651576002974740000E+014f, 1.130315200594948000E+015f, 2.260630401189896000E+015f,
4.521260802379792000E+015f, 9.042521604759584000E+015f, 1.808504320951916800E+016f, 3.617008641903833600E+016f,
7.234017283807667200E+016f, 1.446803456761533400E+017f, 2.893606913523066900E+017f, 5.787213827046133800E+017f,
1.157442765409226800E+018f, 2.314885530818453500E+018f, 4.629771061636907000E+018f, 9.259542123273814000E+018f,
1.851908424654762800E+019f, 3.703816849309525600E+019f, 7.407633698619051200E+019f, 1.481526739723810200E+020f,
2.963053479447620500E+020f, 5.926106958895241000E+020f, 1.185221391779048200E+021f, 2.370442783558096400E+021f,
4.740885567116192800E+021f, 9.481771134232385600E+021f, 1.896354226846477100E+022f, 3.792708453692954200E+022f,
7.585416907385908400E+022f, 1.517083381477181700E+023f, 3.034166762954363400E+023f, 6.068333525908726800E+023f,
1.213666705181745400E+024f, 2.427333410363490700E+024f, 4.854666820726981400E+024f, 9.709333641453962800E+024f,
1.941866728290792600E+025f, 3.883733456581585100E+025f, 7.767466913163170200E+025f, 1.553493382632634000E+026f,
3.106986765265268100E+026f, 6.213973530530536200E+026f, 1.242794706106107200E+027f, 2.485589412212214500E+027f,
4.971178824424429000E+027f, 9.942357648848857900E+027f, 1.988471529769771600E+028f, 3.976943059539543200E+028f,
7.953886119079086300E+028f, 1.590777223815817300E+029f, 3.181554447631634500E+029f, 6.363108895263269100E+029f,
1.272621779052653800E+030f, 2.545243558105307600E+030f, 5.090487116210615300E+030f, 1.018097423242123100E+031f,
2.036194846484246100E+031f, 4.072389692968492200E+031f, 8.144779385936984400E+031f, 1.628955877187396900E+032f,
3.257911754374793800E+032f, 6.515823508749587500E+032f, 1.303164701749917500E+033f, 2.606329403499835000E+033f,
5.212658806999670000E+033f, 1.042531761399934000E+034f, 2.085063522799868000E+034f, 4.170127045599736000E+034f,
8.340254091199472000E+034f, 1.668050818239894400E+035f, 3.336101636479788800E+035f, 6.672203272959577600E+035f
};
// convert texture to linear 0..1 value
public static float TexLightToLinear(int c, int exponent)
{
//extern float power2_n[256];
//Assert(exponent >= -128 && exponent <= 127 );
if (exponent >= -128 && exponent <= 127) return float.NaN;
return (float)c * power2_n[exponent + 128];
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c4dc652aadc78094298f72dd7ce75428
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,37 @@
using System;
namespace SourceFormatParser.Common
{
/// <summary>
/// compressed color format.
/// Size: 4 bytes
/// </summary>
public struct ColorRGBExp32
{
public byte r, g, b, exponent;
public ColorRGBExp32(byte r, byte g, byte b, byte exponent)
{
this.r = r;
this.g = g;
this.b = b;
this.exponent = exponent;
}
/// <summary>
/// Not implemented. mathlib/color_conversion.cpp - "VectorToColorRGBExp32" method if you want to.
/// </summary>
public static ColorRGBExp32 FromVector(SourceVector vin) => throw new NotImplementedException();
public SourceVector ToVector()
{
// FIXME: Why is there a factor of 255 built into this?
return new SourceVector(
255.0f * ColorConversion.TexLightToLinear(r, exponent),
255.0f * ColorConversion.TexLightToLinear(g, exponent),
255.0f * ColorConversion.TexLightToLinear(b, exponent)
);
}
public override string ToString() => $"{{{r}; {g}; {b}; exp={exponent}}}";
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1ed879c18da020a448afe6576e15f627
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,11 @@
namespace SourceFormatParser.Common
{
/// <summary>
/// compressed light cube (6 sides = 6 colors).
/// Size: 24 bytes
/// </summary>
public struct CompressedLightCube
{
public ColorRGBExp32[] m_Color; //[6]
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6f0f3d55aab418b49872ce22a291ea26
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+14
View File
@@ -0,0 +1,14 @@
namespace SourceFormatParser.Common
{
public static class DebugLog
{
public static void Write(object obj)
{
#if UNITY
UnityEngine.Debug.Log(obj);
#else
System.Console.WriteLine(obj);
#endif
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9ca1a75353e50544d89d5c910794abea
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+4
View File
@@ -0,0 +1,4 @@
//not tested.
#if (UNITY_5_1 || UNITY_5_2 || UNITY_5_3_OR_NEWER)
#define UNITY
#endif
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e368deb37419a294aba5cc8c1a97de60
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+38
View File
@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
namespace SourceFormatParser.Common
{
public static class FlagsUtils
{
public static T[] getFlags<T>(int f) where T : Enum
{
T flag = (T)Enum.Parse(typeof(T), f.ToString());
var vals = Enum.GetValues(typeof(T));
int vallen = vals.Length;
List<T> ret = new List<T>();
for (int i = 0; i < vallen; i++)
{
if (f != 0 && (int)vals.GetValue(i) == 0) continue;
T val = (T)vals.GetValue(i);
if (flag.HasFlag(val)) ret.Add(val);
}
return ret.ToArray();
}
public static T[] getFlags<T>(uint f) where T : Enum
{
T flag = (T)Enum.Parse(typeof(T), f.ToString());
var vals = Enum.GetValues(typeof(T));
int vallen = vals.Length;
List<T> ret = new List<T>();
for (int i = 0; i < vallen; i++)
{
if (f != 0 && (int)vals.GetValue(i) == 0) continue;
T val = (T)vals.GetValue(i);
if (flag.HasFlag(val)) ret.Add(val);
}
return ret.ToArray();
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 214c5db74ff395549a83e17197713911
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
namespace SourceFormatParser.Common
{
public static class LightUtils
{
public static byte linearToTexLight(byte c, float exponent) => (byte)MathUtils.Clamp(c * exponent * 0.5f, 0, 255);
public static float linearToTexLightF(byte c, float exponent) => MathUtils.Clamp(c * exponent * 0.5f, 0, 255) / 255.0f;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 57fe4cc545b25df43a52c0a728398c16
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+526
View File
@@ -0,0 +1,526 @@
using System;
namespace SourceFormatParser.Common
{
public static class MathUtils
{
public const float M_PI = 3.14159265358979323846f; // matches value in gcc v2 math.h
public const float M_PI_F = ((float)(M_PI));
public static float RAD2DEG(float x) => ((float)(x) * (float)(180.0f / M_PI_F));
public static float DEG2RAD(float x) => ((float)(x) * (float)(M_PI_F / 180.0f));
public static float Clamp(float val, float min, float max)
{
if (val <= min) return min;
if (val >= max) return max;
return val;
}
public static float Avg(params float[] fs)
{
float avg = 0;
foreach (float f in fs) avg += f;
avg /= fs.Length;
return avg;
}
public static byte Avg(params byte[] bs)
{
int avg = 0;
foreach (byte b in bs) avg += b;
avg /= bs.Length;
return (byte)avg;
}
public static SourceMatrix3x4 AngleMatrix(SourceQAngle angles)
{
//float sr, sp, sy, cr, cp, cy;
//SinCos(DEG2RAD(angles[YAW]), &sy, &cy);
//SinCos(DEG2RAD(angles[PITCH]), &sp, &cp);
//SinCos(DEG2RAD(angles[ROLL]), &sr, &cr);
//SourceMatrix3x4 matrix;
//// matrix = (YAW * PITCH) * ROLL
//matrix[0][0] = cp * cy;
//matrix[1][0] = cp * sy;
//matrix[2][0] = -sp;
//// NOTE: Do not optimize this to reduce multiplies! optimizer bug will screw this up.
//matrix[0][1] = sr * sp * cy + cr * -sy;
//matrix[1][1] = sr * sp * sy + cr * cy;
//matrix[2][1] = sr * cp;
//matrix[0][2] = (cr * sp * cy + -sr * -sy);
//matrix[1][2] = (cr * sp * sy + -sr * cy);
//matrix[2][2] = cr * cp;
//matrix[0][3] = 0.0f;
//matrix[1][3] = 0.0f;
//matrix[2][3] = 0.0f;
//return matrix;
throw new NotImplementedException();
}
public static SourceQuaternion MatrixQuaternion(SourceMatrix3x4 mat)
{
SourceQuaternion tmp = new SourceQuaternion();
MatrixQuaternion(mat, ref tmp);
return tmp;
}
public static void MatrixQuaternion(SourceMatrix3x4 mat, ref SourceQuaternion q)
{
SourceQAngle angles = new SourceQAngle();
MatrixAngles(mat, ref angles);
AngleQuaternion(angles, ref q);
}
public static void MatrixAngles(SourceMatrix3x4 matrix, ref SourceQAngle angles)
{
//MatrixAngles(matrix, out angles.x);
throw new NotImplementedException();
}
public static void AngleQuaternion(SourceQAngle angles, ref SourceQuaternion outQuat)
{
float sr, sp, sy, cr, cp, cy;
SinCos(DEG2RAD(angles.y) * 0.5f, out sy, out cy);
SinCos(DEG2RAD(angles.x) * 0.5f, out sp, out cp);
SinCos(DEG2RAD(angles.z) * 0.5f, out sr, out cr);
// NJS: for some reason VC6 wasn't recognizing the common subexpressions:
float srXcp = sr * cp, crXsp = cr * sp;
outQuat.x = srXcp * cy - crXsp * sy; // X
outQuat.y = crXsp * cy + srXcp * sy; // Y
float crXcp = cr * cp, srXsp = sr * sp;
outQuat.z = crXcp * sy - srXsp * cy; // Z
outQuat.w = crXcp * cy + srXsp * sy; // W (real component)
}
public static void SinCos(float x, out float s, out float c)
{
c = (float)Math.Cos(x);
s = (float)Math.Sin(x);
}
public static void AngleMatrix(SourceQAngle angles, SourceVector position, ref SourceMatrix3x4 matrix)
{
AngleMatrix(angles, ref matrix);
MatrixSetColumn(position, 3, ref matrix);
}
public static void AngleMatrix(SourceQAngle angles, ref SourceMatrix3x4 matrix)
{
float sr, sp, sy, cr, cp, cy;
SinCos(DEG2RAD(angles[1]), out sy, out cy);
SinCos(DEG2RAD(angles[0]), out sp, out cp);
SinCos(DEG2RAD(angles[2]), out sr, out cr);
// matrix = (YAW * PITCH) * ROLL
matrix[0][0] = cp * cy;
matrix[1][0] = cp * sy;
matrix[2][0] = -sp;
// NOTE: Do not optimize this to reduce multiplies! optimizer bug will screw this up.
matrix[0][1] = sr * sp * cy + cr * -sy;
matrix[1][1] = sr * sp * sy + cr * cy;
matrix[2][1] = sr * cp;
matrix[0][2] = (cr * sp * cy + -sr * -sy);
matrix[1][2] = (cr * sp * sy + -sr * cy);
matrix[2][2] = cr * cp;
matrix[0][3] = 0.0f;
matrix[1][3] = 0.0f;
matrix[2][3] = 0.0f;
}
public static void MatrixSetColumn(SourceVector _in, int column, ref SourceMatrix3x4 _out)
{
_out[0][column] = _in.x;
_out[1][column] = _in.y;
_out[2][column] = _in.z;
}
public static void QuaternionAngles(SourceQuaternion q, ref SourceRadianEuler angles)
{
// FIXME: doing it this way calculates too much data, needs to do an optimized version...
SourceMatrix3x4 matrix = new SourceMatrix3x4();
QuaternionMatrix(q, ref matrix);
MatrixAngles(matrix, ref angles);
}
public static void QuaternionMatrix(SourceQuaternion q, ref SourceMatrix3x4 matrix)
{
// Original code
// This should produce the same code as below with optimization, but looking at the assmebly,
// it doesn't. There are 7 extra multiplies in the release build of this, go figure.
matrix[0][0] = 1.0f - 2.0f * q.y * q.y - 2.0f * q.z * q.z;
matrix[1][0] = 2.0f * q.x * q.y + 2.0f * q.w * q.z;
matrix[2][0] = 2.0f * q.x * q.z - 2.0f * q.w * q.y;
matrix[0][1] = 2.0f * q.x * q.y - 2.0f * q.w * q.z;
matrix[1][1] = 1.0f - 2.0f * q.x * q.x - 2.0f * q.z * q.z;
matrix[2][1] = 2.0f * q.y * q.z + 2.0f * q.w * q.x;
matrix[0][2] = 2.0f * q.x * q.z + 2.0f * q.w * q.y;
matrix[1][2] = 2.0f * q.y * q.z - 2.0f * q.w * q.x;
matrix[2][2] = 1.0f - 2.0f * q.x * q.x - 2.0f * q.y * q.y;
matrix[0][3] = 0.0f;
matrix[1][3] = 0.0f;
matrix[2][3] = 0.0f;
}
public static void MatrixAngles(SourceMatrix3x4 matrix, ref SourceRadianEuler angles)
{
float[] a = new float[3];
for (int i = 0; i < 3; i++) a[i] = angles[i];
MatrixAngles(matrix, ref a);
for (int i = 0; i < 3; i++) angles[i] = a[i];
}
public static void MatrixAngles(SourceMatrix3x4 matrix, ref float[] angles)
{
float[] forward = new float[3];
float[] left = new float[3];
float[] up = new float[3];
//
// Extract the basis vectors from the matrix. Since we only need the Z
// component of the up vector, we don't get X and Y.
//
forward[0] = matrix[0][0];
forward[1] = matrix[1][0];
forward[2] = matrix[2][0];
left[0] = matrix[0][1];
left[1] = matrix[1][1];
left[2] = matrix[2][1];
up[2] = matrix[2][2];
float xyDist = (float)(Math.Sqrt(forward[0] * forward[0] + forward[1] * forward[1]));
// enough here to get angles?
if (xyDist > 0.001f)
{
// (yaw) y = ATAN( forward.y, forward.x ); -- in our space, forward is the X axis
angles[1] = RAD2DEG((float)Math.Atan2(forward[1], forward[0]));
// (pitch) x = ATAN( -forward.z, sqrt(forward.x*forward.x+forward.y*forward.y) );
angles[0] = RAD2DEG((float)Math.Atan2(-forward[2], xyDist));
// (roll) z = ATAN( left.z, up.z );
angles[2] = RAD2DEG((float)Math.Atan2(left[2], up[2]));
}
else // forward is mostly Z, gimbal lock-
{
// (yaw) y = ATAN( -left.x, left.y ); -- forward is mostly z, so use right for yaw
angles[1] = RAD2DEG((float)Math.Atan2(-left[0], left[1]));
// (pitch) x = ATAN( -forward.z, sqrt(forward.x*forward.x+forward.y*forward.y) );
angles[0] = RAD2DEG((float)Math.Atan2(-forward[2], xyDist));
// Assume no roll in this case as one degree of freedom has been lost (i.e. yaw == roll)
angles[2] = 0;
}
}
public static void QuaternionAngles(SourceQuaternion q, ref SourceQAngle angles)
{
// FIXME: doing it this way calculates too much data, needs to do an optimized version...
SourceMatrix3x4 matrix = new SourceMatrix3x4();
QuaternionMatrix(q, ref matrix);
MatrixAngles(matrix, ref angles);
}
public static void AngleQuaternion(SourceRadianEuler angles, ref SourceQuaternion outQuat)
{
float sr, sp, sy, cr, cp, cy;
SinCos(angles.z * 0.5f, out sy, out cy);
SinCos(angles.y * 0.5f, out sp, out cp);
SinCos(angles.x * 0.5f, out sr, out cr);
// NJS: for some reason VC6 wasn't recognizing the common subexpressions:
float srXcp = sr * cp, crXsp = cr * sp;
outQuat.x = srXcp * cy - crXsp * sy; // X
outQuat.y = crXsp * cy + srXcp * sy; // Y
float crXcp = cr * cp, srXsp = sr * sp;
outQuat.z = crXcp * sy - srXsp * cy; // Z
outQuat.w = crXcp * cy + srXsp * sy; // W (real component)
}
public static SourceMatrix3x4 TransformMatrix(SourceCTransform _in)
{
SourceMatrix3x4 _out = new SourceMatrix3x4();
TransformMatrix(_in, ref _out);
return _out;
}
public static void TransformMatrix(SourceCTransform _in, ref SourceMatrix3x4 _out)
{
QuaternionMatrix(_in.m_orientation, _in.m_vPosition, ref _out);
}
public static void QuaternionMatrix(SourceQuaternion q, SourceVector pos, ref SourceMatrix3x4 matrix)
{
QuaternionMatrix(q, ref matrix);
matrix[0][3] = pos.x;
matrix[1][3] = pos.y;
matrix[2][3] = pos.z;
}
public static void TransformVectorsFLU(SourceCTransform _in, ref SourceVector pForward, ref SourceVector pLeft, ref SourceVector pUp)
{
QuaternionVectorsFLU(_in.m_orientation, ref pForward, ref pLeft, ref pUp);
}
public static void QuaternionVectorsFLU(SourceQuaternion q, ref SourceVector pForward, ref SourceVector pLeft, ref SourceVector pUp)
{
// Note: it's pretty much identical to just computing the quaternion matrix and assigning its columns to the vectors
pForward = q.GetForward();
pLeft = q.GetLeft();
pUp = q.GetUp();
}
public static void TransformVectorsForward(SourceCTransform _in, ref SourceVector pForward)
{
QuaternionVectorsForward(_in.m_orientation, ref pForward);
}
public static void QuaternionVectorsForward(SourceQuaternion q, ref SourceVector pForward)
{
pForward = q.GetForward();
}
public static SourceVector TransformPoint(SourceCTransform tm, SourceVector p)
{
return new SourceVector(
tm.m_vPosition.x + (1.0f - 2.0f * tm.m_orientation.y * tm.m_orientation.y - 2.0f * tm.m_orientation.z * tm.m_orientation.z) * p.x + (2.0f * tm.m_orientation.x * tm.m_orientation.y - 2.0f * tm.m_orientation.w * tm.m_orientation.z) * p.y + (2.0f * tm.m_orientation.x * tm.m_orientation.z + 2.0f * tm.m_orientation.w * tm.m_orientation.y) * p.z,
tm.m_vPosition.y + (2.0f * tm.m_orientation.x * tm.m_orientation.y + 2.0f * tm.m_orientation.w * tm.m_orientation.z) * p.x + (1.0f - 2.0f * tm.m_orientation.x * tm.m_orientation.x - 2.0f * tm.m_orientation.z * tm.m_orientation.z) * p.y + (2.0f * tm.m_orientation.y * tm.m_orientation.z - 2.0f * tm.m_orientation.w * tm.m_orientation.x) * p.z,
tm.m_vPosition.z + (2.0f * tm.m_orientation.x * tm.m_orientation.z - 2.0f * tm.m_orientation.w * tm.m_orientation.y) * p.x + (2.0f * tm.m_orientation.y * tm.m_orientation.z + 2.0f * tm.m_orientation.w * tm.m_orientation.x) * p.y + (1.0f - 2.0f * tm.m_orientation.x * tm.m_orientation.x - 2.0f * tm.m_orientation.y * tm.m_orientation.y) * p.z
);
}
public static void RotatePoint(SourceCTransform tm, SourceVector p, ref SourceVector _out)
{
_out.x = (1.0f - 2.0f * tm.m_orientation.y * tm.m_orientation.y - 2.0f * tm.m_orientation.z * tm.m_orientation.z) * p.x + (2.0f * tm.m_orientation.x * tm.m_orientation.y - 2.0f * tm.m_orientation.w * tm.m_orientation.z) * p.y + (2.0f * tm.m_orientation.x * tm.m_orientation.z + 2.0f * tm.m_orientation.w * tm.m_orientation.y) * p.z;
_out.y = (2.0f * tm.m_orientation.x * tm.m_orientation.y + 2.0f * tm.m_orientation.w * tm.m_orientation.z) * p.x + (1.0f - 2.0f * tm.m_orientation.x * tm.m_orientation.x - 2.0f * tm.m_orientation.z * tm.m_orientation.z) * p.y + (2.0f * tm.m_orientation.y * tm.m_orientation.z - 2.0f * tm.m_orientation.w * tm.m_orientation.x) * p.z;
_out.z = (2.0f * tm.m_orientation.x * tm.m_orientation.z - 2.0f * tm.m_orientation.w * tm.m_orientation.y) * p.x + (2.0f * tm.m_orientation.y * tm.m_orientation.z + 2.0f * tm.m_orientation.w * tm.m_orientation.x) * p.y + (1.0f - 2.0f * tm.m_orientation.x * tm.m_orientation.x - 2.0f * tm.m_orientation.y * tm.m_orientation.y) * p.z;
}
public static void VectorITransform(SourceVector v, SourceCTransform t, ref SourceVector _out)
{
// FIXME: Make work directly with the transform
SourceMatrix3x4 m = new SourceMatrix3x4();
TransformMatrix(t, ref m);
VectorITransform(v, m, ref _out);
}
public static void VectorITransform(SourceVector in1, SourceMatrix3x4 in2, ref SourceVector _out)
{
throw new NotImplementedException();
//VectorITransform(in1.x, in2, ref _out.x);
}
public static void VectorIRotate(SourceVector v, SourceCTransform t, ref SourceVector _out)
{
// FIXME: Make work directly with the transform
SourceMatrix3x4 m = new SourceMatrix3x4();
TransformMatrix(t, ref m);
VectorIRotate(v, m, ref _out);
}
public static void VectorIRotate(SourceVector in1, SourceMatrix3x4 in2, ref SourceVector _out)
{
throw new NotImplementedException();
//VectorIRotate( in1.x, in2, ref _out.x );
}
public static void TransformAABB(SourceMatrix3x4 transform, SourceVector vecMinsIn, SourceVector vecMaxsIn, ref SourceVector vecMinsOut, ref SourceVector vecMaxsOut)
{
throw new NotImplementedException(); //can't find some of methods
//SourceVector localCenter;
//VectorAdd(vecMinsIn, vecMaxsIn, localCenter);
//localCenter *= 0.5f;
//SourceVector localExtents;
//VectorSubtract(vecMaxsIn, localCenter, localExtents);
//SourceVector worldCenter;
//VectorTransform(localCenter, transform, worldCenter);
//SourceVector worldExtents;
//worldExtents.x = DotProductAbs(localExtents, transform[0]);
//worldExtents.y = DotProductAbs(localExtents, transform[1]);
//worldExtents.z = DotProductAbs(localExtents, transform[2]);
//VectorSubtract(worldCenter, worldExtents, vecMinsOut);
//VectorAdd(worldCenter, worldExtents, vecMaxsOut);
}
public static void ITransformAABB(SourceMatrix3x4 transform, SourceVector vecMinsIn, SourceVector vecMaxsIn, ref SourceVector vecMinsOut, ref SourceVector vecMaxsOut)
{
throw new NotImplementedException(); //can't find some of methods
// SourceVector worldCenter;
// VectorAdd(vecMinsIn, vecMaxsIn, worldCenter );
// worldCenter *= 0.5f;
// SourceVector worldExtents;
// VectorSubtract(vecMaxsIn, worldCenter, worldExtents );
// Vector localCenter;
// VectorITransform(worldCenter, transform, localCenter );
// Vector localExtents;
// localExtents.x = FloatMakePositive(worldExtents.x* transform[0][0] ) +
//FloatMakePositive(worldExtents.y* transform[1][0] ) +
//FloatMakePositive(worldExtents.z* transform[2][0] );
// localExtents.y = FloatMakePositive(worldExtents.x* transform[0][1] ) +
//FloatMakePositive(worldExtents.y* transform[1][1] ) +
//FloatMakePositive(worldExtents.z* transform[2][1] );
// localExtents.z = FloatMakePositive(worldExtents.x* transform[0][2] ) +
//FloatMakePositive(worldExtents.y* transform[1][2] ) +
//FloatMakePositive(worldExtents.z* transform[2][2] );
// VectorSubtract(localCenter, localExtents, vecMinsOut );
// VectorAdd(localCenter, localExtents, vecMaxsOut );
}
public static void RotateAABB(SourceMatrix3x4 transform, SourceVector vecMinsIn, SourceVector vecMaxsIn, ref SourceVector vecMinsOut, ref SourceVector vecMaxsOut)
{
throw new NotImplementedException(); //can't find some of methods
//SourceVector localCenter;
//VectorAdd(vecMinsIn, vecMaxsIn, localCenter);
//localCenter *= 0.5f;
//SourceVector localExtents;
//VectorSubtract(vecMaxsIn, localCenter, localExtents);
//SourceVector newCenter;
//VectorRotate(localCenter, transform, newCenter);
//VecSourceVectortor newExtents;
//newExtents.x = DotProductAbs(localExtents, transform[0]);
//newExtents.y = DotProductAbs(localExtents, transform[1]);
//newExtents.z = DotProductAbs(localExtents, transform[2]);
//VectorSubtract(newCenter, newExtents, vecMinsOut);
//VectorAdd(newCenter, newExtents, vecMaxsOut);
}
public static void IRotateAABB(SourceMatrix3x4 transform, SourceVector vecMinsIn, SourceVector vecMaxsIn, ref SourceVector vecMinsOut, ref SourceVector vecMaxsOut)
{
throw new NotImplementedException(); //can't find some of methods
//SourceVector oldCenter;
//VectorAdd(vecMinsIn, vecMaxsIn, oldCenter);
//oldCenter *= 0.5f;
//SourceVector oldExtents;
//VectorSubtract(vecMaxsIn, oldCenter, oldExtents);
//SourceVector newCenter;
//VectorIRotate(oldCenter, transform, newCenter);
//SourceVector newExtents;
//newExtents.x = FloatMakePositive(oldExtents.x * transform[0][0]) +
// FloatMakePositive(oldExtents.y * transform[1][0]) +
// FloatMakePositive(oldExtents.z * transform[2][0]);
//newExtents.y = FloatMakePositive(oldExtents.x * transform[0][1]) +
// FloatMakePositive(oldExtents.y * transform[1][1]) +
// FloatMakePositive(oldExtents.z * transform[2][1]);
//newExtents.z = FloatMakePositive(oldExtents.x * transform[0][2]) +
// FloatMakePositive(oldExtents.y * transform[1][2]) +
// FloatMakePositive(oldExtents.z * transform[2][2]);
//VectorSubtract(newCenter, newExtents, vecMinsOut);
//VectorAdd(newCenter, newExtents, vecMaxsOut);
}
public static void MatrixInvert(SourceMatrix3x4 _in, ref SourceMatrix3x4 _out)
{
if (_in == _out)
{
V_swap(ref _out[0][1], ref _out[1][0]);
V_swap(ref _out[0][2], ref _out[2][0]);
V_swap(ref _out[1][2], ref _out[2][1]);
}
else
{
// transpose the matrix
_out[0][0] = _in[0][0];
_out[0][1] = _in[1][0];
_out[0][2] = _in[2][0];
_out[1][0] = _in[0][1];
_out[1][1] = _in[1][1];
_out[1][2] = _in[2][1];
_out[2][0] = _in[0][2];
_out[2][1] = _in[1][2];
_out[2][2] = _in[2][2];
}
// now fix up the translation to be in the other space
float[] tmp = new float[3];
tmp[0] = _in[0][3];
tmp[1] = _in[1][3];
tmp[2] = _in[2][3];
_out[0][3] = -DotProduct(tmp, _out[0]);
_out[1][3] = -DotProduct(tmp, _out[1]);
_out[2][3] = -DotProduct(tmp, _out[2]);
}
public static void V_swap<T>(ref T x, ref T y)
{
T temp = x;
x = y;
y = temp;
}
public static float DotProduct(float[] a, float[] b) => a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
public static void AngleMatrix(SourceRadianEuler angles, SourceVector position, ref SourceMatrix3x4 matrix)
{
AngleMatrix(angles, ref matrix);
MatrixSetColumn(position, 3, ref matrix);
}
public static void AngleMatrix(SourceRadianEuler angles, ref SourceMatrix3x4 matrix)
{
SourceQAngle quakeEuler = new SourceQAngle(RAD2DEG(angles.y), RAD2DEG(angles.z), RAD2DEG(angles.x));
AngleMatrix(quakeEuler, ref matrix);
}
public static SourceCTransform MatrixTransform(SourceMatrix3x4 _in)
{
SourceCTransform _out = new SourceCTransform();
MatrixTransform(_in, ref _out);
return _out;
}
public static void MatrixTransform(SourceMatrix3x4 _in, ref SourceCTransform _out)
{
MatrixQuaternion(_in, ref _out.m_orientation);
MatrixGetColumn(_in, 3, ref _out.m_vPosition);
}
public static void MatrixGetColumn(SourceMatrix3x4 _in, int column, ref SourceVector _out)
{
_out.x = _in[0][column];
_out.y = _in[1][column];
_out.z = _in[2][column];
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b9c40dc28e7e1a7479f5461294fefd74
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,66 @@
using System.IO;
using System.Text;
namespace SourceFormatParser.Common
{
public static class ParsingUtils
{
public static SourceVector ReadVector(this BinaryReader BR) => new SourceVector(BR.ReadSingle(), BR.ReadSingle(), BR.ReadSingle());
public static SourceVectorShort ReadVectorShort(this BinaryReader BR) => new SourceVectorShort(BR.ReadInt16(), BR.ReadInt16(), BR.ReadInt16());
public static SourceVector2 ReadVector2(this BinaryReader BR) => new SourceVector2(BR.ReadSingle(), BR.ReadSingle());
public static SourceVector2Short ReadVector2Short(this BinaryReader BR) => new SourceVector2Short(BR.ReadInt16(), BR.ReadInt16());
public static SourceVector2Int ReadVector2Int(this BinaryReader BR) => new SourceVector2Int(BR.ReadInt32(), BR.ReadInt32());
public static SourceVector4 ReadVector4(this BinaryReader BR) => new SourceVector4(BR.ReadSingle(), BR.ReadSingle(), BR.ReadSingle(), BR.ReadSingle());
public static SourceQAngle ReadQAngle(this BinaryReader BR) => new SourceQAngle(BR.ReadSingle(), BR.ReadSingle(), BR.ReadSingle());
public static SourceQuaternion ReadQuaternion(this BinaryReader BR) => new SourceQuaternion(BR.ReadSingle(), BR.ReadSingle(), BR.ReadSingle(), BR.ReadSingle());
public static SourceRadianEuler ReadRadianEuler(this BinaryReader BR) => new SourceRadianEuler(BR.ReadSingle(), BR.ReadSingle(), BR.ReadSingle());
public static SourceMatrix3x4 ReadMatrix3x4(this BinaryReader BR) => new SourceMatrix3x4(BR.ReadVector(), BR.ReadVector(), BR.ReadVector(), BR.ReadVector());
public static SourceColor32 ReadColor32(this BinaryReader BR) => new SourceColor32(BR.ReadByte(), BR.ReadByte(), BR.ReadByte(), BR.ReadByte());
public static ColorRGBExp32 ReadColorRGBExp32(this BinaryReader BR) => new ColorRGBExp32(BR.ReadByte(), BR.ReadByte(), BR.ReadByte(), BR.ReadByte());
public static CompressedLightCube ReadCompressedLightCube(this BinaryReader BR) => new CompressedLightCube {
m_Color = new ColorRGBExp32[6] {
ReadColorRGBExp32(BR), ReadColorRGBExp32(BR), ReadColorRGBExp32(BR), ReadColorRGBExp32(BR), ReadColorRGBExp32(BR), ReadColorRGBExp32(BR)
}
};
#region Read Array
public static ushort[] ReadUInt16Array(this BinaryReader BR, int count)
{
ushort[] ret = new ushort[count];
for (int c = 0; c < count; c++) ret[c] = BR.ReadUInt16();
return ret;
}
public static short[] ReadInt16Array(this BinaryReader BR, int count)
{
short[] ret = new short[count];
for (int c = 0; c < count; c++) ret[c] = BR.ReadInt16();
return ret;
}
public static uint[] ReadUInt32Array(this BinaryReader BR, int count)
{
uint[] ret = new uint[count];
for (int c = 0; c < count; c++) ret[c] = BR.ReadUInt32();
return ret;
}
public static int[] ReadInt32Array(this BinaryReader BR, int count)
{
int[] ret = new int[count];
for (int c = 0; c < count; c++) ret[c] = BR.ReadInt32();
return ret;
}
public static float[] ReadSingleArray(this BinaryReader BR, int count)
{
float[] ret = new float[count];
for (int c = 0; c < count; c++) ret[c] = BR.ReadSingle();
return ret;
}
#endregion
public static string ReadString(this BinaryReader BR, int count) => Encoding.ASCII.GetString(BR.ReadBytes(64)).Replace("\0", "");
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 60518559dfb0da7408790faa0dc034c3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,30 @@
namespace SourceFormatParser.Common
{
/// <summary>
/// compressed color rgba format.
/// Size: 4 bytes
/// </summary>
public struct SourceColor32
{
public byte r, g, b, a;
public SourceColor32(byte r, byte g, byte b, byte a)
{
this.r = r;
this.g = g;
this.b = b;
this.a = a;
}
public SourceColor32(float r, float g, float b, float a)
{
this.r = (byte)(r * 255);
this.g = (byte)(g * 255);
this.b = (byte)(b * 255);
this.a = (byte)(a * 255);
}
public SourceVector toSVector() => new SourceVector(r * (1.0f / 255.0f), g * (1.0f / 255.0f), b * (1.0f / 255.0f));
public override string ToString() => $"{{{r}; {g}; {b}; {a}}}";
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: aa45776704098ca46a06f71dbadadb98
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b5d883a90443a954aa51477cd9deff83
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,126 @@
using System;
namespace SourceFormatParser.Common
{
public class SourceCTransform
{
public SourceCTransform() { }
public SourceCTransform(SourceVector v, SourceQuaternion q)
{
m_vPosition = v;
m_orientation = q;
}
public SourceCTransform(SourceVector v, SourceQAngle a)
{
m_vPosition = v;
MathUtils.AngleQuaternion(a, ref m_orientation);
}
public SourceVector m_vPosition;
public SourceQuaternion m_orientation;
public bool IsValid()
{
//return m_vPosition.IsValid() && m_orientation.IsValid();
throw new NotImplementedException();
}
public static bool operator ==(SourceCTransform c1, SourceCTransform c2) => c1.m_vPosition == c2.m_vPosition && c1.m_orientation == c2.m_orientation; //< exact equality check
public static bool operator !=(SourceCTransform c1, SourceCTransform c2) => !(c1 == c2);
public override bool Equals(object obj) => this == (SourceCTransform)obj;
public override int GetHashCode() => base.GetHashCode();
// for API compatibility with matrix3x4_t
public void InitFromQAngles(SourceQAngle angles, SourceVector vPosition)
{
MathUtils.AngleQuaternion(angles, ref m_orientation);
m_vPosition = vPosition;
}
public void InitFromMatrix(SourceMatrix3x4 transform)
{
m_orientation = MathUtils.MatrixQuaternion(transform);
m_vPosition = transform.GetOrigin();
}
public void InitFromQuaternion(SourceQuaternion orientation, SourceVector vPosition)
{
m_orientation = orientation;
m_vPosition = vPosition;
}
public SourceQuaternion ToQuaternion() => m_orientation;
public SourceQAngle ToQAngle()
{
SourceQAngle angles = new SourceQAngle();
MathUtils.QuaternionAngles(m_orientation, ref angles);
return angles;
}
public SourceMatrix3x4 ToMatrix() => MathUtils.TransformMatrix(this);
public void SetToIdentity()
{
m_vPosition = SourceVector.Empty;
m_orientation = SourceQuaternion.Identity;
}
public void SetOrigin(SourceVector vPos) { m_vPosition = vPos; }
public void SetAngles(SourceQAngle vAngles) { MathUtils.AngleQuaternion(vAngles, ref m_orientation); }
public SourceVector GetOrigin() { return m_vPosition; }
public void GetBasisVectorsFLU(ref SourceVector pForward, ref SourceVector pLeft, ref SourceVector pUp)
{
MathUtils.TransformVectorsFLU(this, ref pForward, ref pLeft, ref pUp);
}
public SourceVector GetForward()
{
SourceVector vForward = new SourceVector();
MathUtils.TransformVectorsForward(this, ref vForward);
return vForward;
}
public SourceVector TransformVector(SourceVector v0) => MathUtils.TransformPoint(this, v0);
public SourceVector RotateVector(SourceVector v0)
{
SourceVector vOut = new SourceVector();
MathUtils.RotatePoint(this, v0, ref vOut);
return vOut;
}
public SourceVector TransformVectorByInverse(SourceVector v0)
{
SourceVector vOut = new SourceVector();
MathUtils.VectorITransform(v0, this, ref vOut);
return vOut;
}
public SourceVector RotateVectorByInverse(SourceVector v0)
{
SourceVector vOut = new SourceVector();
MathUtils.VectorIRotate(v0, this, ref vOut);
return vOut;
}
public SourceVector RotateExtents(SourceVector vBoxExtents) { throw new NotImplementedException(); } // these are extents and must remain positive/symmetric after rotation
public void TransformAABB(SourceVector vecMinsIn, SourceVector vecMaxsIn, ref SourceVector vecMinsOut, ref SourceVector vecMaxsOut)
{
ToMatrix().TransformAABB(vecMinsIn, vecMaxsIn, ref vecMinsOut, ref vecMaxsOut);
}
public void TransformAABBByInverse(SourceVector vecMinsIn, SourceVector vecMaxsIn, ref SourceVector vecMinsOut, ref SourceVector vecMaxsOut)
{
ToMatrix().TransformAABBByInverse(vecMinsIn, vecMaxsIn, ref vecMinsOut, ref vecMaxsOut);
}
public void RotateAABB(SourceVector vecMinsIn, SourceVector vecMaxsIn, ref SourceVector vecMinsOut, ref SourceVector vecMaxsOut)
{
ToMatrix().RotateAABB(vecMinsIn, vecMaxsIn, ref vecMinsOut, ref vecMaxsOut);
}
public void RotateAABBByInverse(SourceVector vecMinsIn, SourceVector vecMaxsIn, ref SourceVector vecMinsOut, ref SourceVector vecMaxsOut)
{
ToMatrix().RotateAABBByInverse(vecMinsIn, vecMaxsIn, ref vecMinsOut, ref vecMaxsOut);
}
//inline void TransformPlane( const cplane_t &inPlane, cplane_t &outPlane ) const;
//inline void InverseTransformPlane( const cplane_t &inPlane, cplane_t &outPlane ) const;
/// Computes an inverse. Uses the 'TR' naming to be consistent with the same method in matrix3x4_t (which only works with orthonormal matrices)
public void InverseTR(ref SourceCTransform _out)
{
SourceMatrix3x4 xForm = ToMatrix();
_out = xForm.InverseTR().ToCTransform();
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6fe3919ba3838be48be45220405d6dcb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,69 @@
using System;
namespace SourceFormatParser.Common
{
/// <summary>Degree Euler angle aligned to axis (NOT ROLL/PITCH/YAW)</summary>
public class SourceDegreeEuler
{
public SourceDegreeEuler() { }
public SourceDegreeEuler(float X, float Y, float Z) { x = X; y = Y; z = Z; }
public SourceDegreeEuler(SourceQuaternion q)
{
SourceRadianEuler radians = new SourceRadianEuler(q);
Init(MathUtils.RAD2DEG(radians.x), MathUtils.RAD2DEG(radians.y), MathUtils.RAD2DEG(radians.z));
}
public SourceDegreeEuler(SourceQAngle angles)
{
Init(angles.z, angles.x, angles.y);
}
public SourceDegreeEuler(SourceRadianEuler angles)
{
Init(MathUtils.RAD2DEG(angles.x), MathUtils.RAD2DEG(angles.y), MathUtils.RAD2DEG(angles.z));
}
// Initialization
public void Init(float ix = 0.0f, float iy = 0.0f, float iz = 0.0f) { x = ix; y = iy; z = iz; }
public SourceQAngle ToQAngle() => new SourceQAngle(y, z, x);
// conversion to qangle
public bool IsValid() { throw new NotImplementedException(); }
public void Invalidate() { throw new NotImplementedException(); }
public float Base() { return x; }
// array access...
public float this[int i]
{
get
{
switch (i)
{
case 0: return x;
case 1: return y;
case 2: return z;
default: throw new Exception("wrong index [0..2]");
}
}
set
{
switch (i)
{
case 0:
x = value;
break;
case 1:
y = value;
break;
case 2:
z = value;
break;
default:
throw new Exception("wrong index [0..2]");
}
}
}
public float x, y, z;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 14e01e0782293504ebe7b80d0a29eed8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,252 @@
namespace SourceFormatParser.Common
{
/// <summary>
/// Matrix 3x4 (float)
/// Size: 48 bytes (4 bytes per val)
/// </summary>
public class SourceMatrix3x4
{
public SourceMatrix3x4() { }
public SourceMatrix3x4(float m00, float m01, float m02, float m03,
float m10, float m11, float m12, float m13,
float m20, float m21, float m22, float m23)
{
m_flMatVal[0][0] = m00; m_flMatVal[0][1] = m01; m_flMatVal[0][2] = m02; m_flMatVal[0][3] = m03;
m_flMatVal[1][0] = m10; m_flMatVal[1][1] = m11; m_flMatVal[1][2] = m12; m_flMatVal[1][3] = m13;
m_flMatVal[2][0] = m20; m_flMatVal[2][1] = m21; m_flMatVal[2][2] = m22; m_flMatVal[2][3] = m23;
}
/// Creates a matrix where the X axis = forward the Y axis = left, and the Z axis = up
void InitXYZ(SourceVector xAxis, SourceVector yAxis, SourceVector zAxis, SourceVector vecOrigin)
{
m_flMatVal[0][0] = xAxis.x; m_flMatVal[0][1] = yAxis.x; m_flMatVal[0][2] = zAxis.x; m_flMatVal[0][3] = vecOrigin.x;
m_flMatVal[1][0] = xAxis.y; m_flMatVal[1][1] = yAxis.y; m_flMatVal[1][2] = zAxis.y; m_flMatVal[1][3] = vecOrigin.y;
m_flMatVal[2][0] = xAxis.z; m_flMatVal[2][1] = yAxis.z; m_flMatVal[2][2] = zAxis.z; m_flMatVal[2][3] = vecOrigin.z;
}
//-----------------------------------------------------------------------------
// Creates a matrix where the X axis = forward
// the Y axis = left, and the Z axis = up
//-----------------------------------------------------------------------------
void Init(SourceVector xAxis, SourceVector yAxis, SourceVector zAxis, SourceVector vecOrigin)
{
m_flMatVal[0][0] = xAxis.x; m_flMatVal[0][1] = yAxis.x; m_flMatVal[0][2] = zAxis.x; m_flMatVal[0][3] = vecOrigin.x;
m_flMatVal[1][0] = xAxis.y; m_flMatVal[1][1] = yAxis.y; m_flMatVal[1][2] = zAxis.y; m_flMatVal[1][3] = vecOrigin.y;
m_flMatVal[2][0] = xAxis.z; m_flMatVal[2][1] = yAxis.z; m_flMatVal[2][2] = zAxis.z; m_flMatVal[2][3] = vecOrigin.z;
}
//-----------------------------------------------------------------------------
// Creates a matrix where the X axis = forward
// the Y axis = left, and the Z axis = up
//-----------------------------------------------------------------------------
public SourceMatrix3x4(SourceVector xAxis, SourceVector yAxis, SourceVector zAxis, SourceVector vecOrigin)
{
Init(xAxis, yAxis, zAxis, vecOrigin);
}
public void InitFromQAngles(SourceQAngle angles, SourceVector vPosition)
{
var t = this;
MathUtils.AngleMatrix(angles, vPosition, ref t);
this.m_flMatVal = t.m_flMatVal;
}
public void InitFromQAngles(SourceQAngle angles) { InitFromQAngles(angles, SourceVector.Empty); }
public void InitFromRadianEuler(SourceRadianEuler angles, SourceVector vPosition)
{
var t = this;
MathUtils.AngleMatrix(angles, vPosition, ref t);
this.m_flMatVal = t.m_flMatVal;
}
public void InitFromRadianEuler(SourceRadianEuler angles) { InitFromRadianEuler(angles, SourceVector.Empty); }
public void InitFromCTransform(SourceCTransform transform)
{
var t = this;
MathUtils.TransformMatrix(transform, ref t);
this.m_flMatVal = t.m_flMatVal;
}
public void InitFromQuaternion(SourceQuaternion orientation, SourceVector vPosition)
{
var t = this;
MathUtils.QuaternionMatrix(orientation, vPosition, ref t);
this.m_flMatVal = t.m_flMatVal;
}
public void InitFromQuaternion(SourceQuaternion orientation) { InitFromQuaternion(orientation, SourceVector.Empty); }
public void InitFromDiagonal(SourceVector vDiagonal)
{
SetToIdentity();
m_flMatVal[0][0] = vDiagonal.x;
m_flMatVal[1][1] = vDiagonal.y;
m_flMatVal[2][2] = vDiagonal.z;
}
public SourceQuaternion ToQuaternion() => MathUtils.MatrixQuaternion(this);
public SourceQAngle ToQAngle()
{
SourceQAngle tmp = new SourceQAngle();
MathUtils.MatrixAngles(this, ref tmp);
return tmp;
}
public SourceCTransform ToCTransform() => MathUtils.MatrixTransform(this);
public void SetToIdentity()
{
for (int i1 = 0; i1 < m_flMatVal.Length; i1++)
for (int i2 = 0; i2 < m_flMatVal[i1].Length; i2++)
m_flMatVal[i1][i2] = 0.0f;
m_flMatVal[0][0] = 1.0f;
m_flMatVal[1][1] = 1.0f;
m_flMatVal[2][2] = 1.0f;
}
/// multiply the scale/rot part of the matrix by a constant. This doesn't init the matrix ,
/// just scale in place. So if you want to construct a scaling matrix, init to identity and
/// then call this.
public void ScaleUpper3x3Matrix(float flScale)
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
m_flMatVal[i][j] *= flScale;
}
}
}
/// modify the origin
public void SetOrigin(SourceVector p)
{
m_flMatVal[0][3] = p.x;
m_flMatVal[1][3] = p.y;
m_flMatVal[2][3] = p.z;
}
/// return the origin
public SourceVector GetOrigin()
{
return new SourceVector(m_flMatVal[0][3], m_flMatVal[1][3], m_flMatVal[2][3]);
}
void Invalidate()
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
m_flMatVal[i][j] = float.NaN;
}
}
}
/// check all components for invalid floating point values
bool IsValid()
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
if (m_flMatVal[i][j] == float.NaN)
return false;
}
}
return true;
}
public static bool operator ==(SourceMatrix3x4 m1, SourceMatrix3x4 m2)
{
bool equals = true;
for (int i1 = 0; i1 < 3; i1++)
{
if (!equals) break;
for (int i2 = 0; i2 < 4; i2++)
{
if (m1[i1][i2] != m2[i1][i2])
{
equals = false;
break;
}
}
}
return equals;
}
public static bool operator !=(SourceMatrix3x4 m1, SourceMatrix3x4 m2) => !(m1 == m2);
public override bool Equals(object obj) => this == (SourceMatrix3x4)obj;
public override int GetHashCode() => base.GetHashCode();
// bool IsEqualTo( const SourceMatrix3x4 &other, float flTolerance = 1e-5f) const;
//void GetBasisVectorsFLU(Vector* pForward, Vector* pLeft, Vector* pUp) const;
//SourceVector TransformVector( const Vector &v0 ) const;
//SourceVector RotateVector( const Vector &v0 ) const;
//SourceVector TransformVectorByInverse( const Vector &v0 ) const;
//SourceVector RotateVectorByInverse( const Vector &v0 ) const;
//SourceVector RotateExtents( const Vector &vBoxExtents ) const; // these are extents and must remain positive/symmetric after rotation
public void TransformAABB(SourceVector vecMinsIn, SourceVector vecMaxsIn, ref SourceVector vecMinsOut, ref SourceVector vecMaxsOut)
{
MathUtils.TransformAABB(this, vecMinsIn, vecMaxsIn, ref vecMinsOut, ref vecMaxsOut);
}
public void TransformAABBByInverse(SourceVector vecMinsIn, SourceVector vecMaxsIn, ref SourceVector vecMinsOut, ref SourceVector vecMaxsOut)
{
MathUtils.ITransformAABB(this, vecMinsIn, vecMaxsIn, ref vecMinsOut, ref vecMaxsOut);
}
public void RotateAABB(SourceVector vecMinsIn, SourceVector vecMaxsIn, ref SourceVector vecMinsOut, ref SourceVector vecMaxsOut)
{
MathUtils.RotateAABB(this, vecMinsIn, vecMaxsIn, ref vecMinsOut, ref vecMaxsOut);
}
public void RotateAABBByInverse(SourceVector vecMinsIn, SourceVector vecMaxsIn, ref SourceVector vecMinsOut, ref SourceVector vecMaxsOut)
{
MathUtils.IRotateAABB(this, vecMinsIn, vecMaxsIn, ref vecMinsOut, ref vecMaxsOut);
}
//void TransformPlane( const cplane_t &inPlane, cplane_t &outPlane ) const;
//void TransformPlaneByInverse( const cplane_t &inPlane, cplane_t &outPlane ) const;
//float GetOrthogonalityError() const;
//float GetDeterminant()const;
//float GetSylvestersCriterion()const; // for symmetrical matrices only: should be >0 iff it's a positive definite matrix
//SourceVector GetColumn(MatrixAxisType_t nColumn) const;
//void SetColumn( const Vector &vColumn, MatrixAxisType_t nColumn);
//SourceVector GetForward() const { return GetColumn(FORWARD_AXIS ); }
// SourceVector GetLeft() const { return GetColumn(LEFT_AXIS ); }
// SourceVector GetUp() const { return GetColumn(UP_AXIS ); }
// SourceVector GetRow(int nRow) const { return * (Vector*) (m_flMatVal[nRow]); }
// void SetRow(int nRow, const Vector &vRow ) { m_flMatVal[nRow][0] = vRow.x; m_flMatVal[nRow][1] = vRow.y; m_flMatVal[nRow][2] = vRow.z; }
public void InverseTR(ref SourceMatrix3x4 _out)
{
MathUtils.MatrixInvert(this, ref _out);
}
public SourceMatrix3x4 InverseTR()
{
SourceMatrix3x4 _out = new SourceMatrix3x4();
InverseTR(ref _out);
return _out;
}
public float[] this[int i]
{
get => m_flMatVal[i];
set => m_flMatVal[i] = value;
}
public float Base() { return m_flMatVal[0][0]; }
float[][] _m_flMatVal;
public float[][] m_flMatVal//[3][4];
{
get
{
if (_m_flMatVal == null)
{
_m_flMatVal = new float[3][];
for (int v = 0; v < 3; v++)
_m_flMatVal[v] = new float[4];
}
return _m_flMatVal;
}
set
{
_m_flMatVal = value;
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6a4f71b4e3573b54c9258fddae8a25e8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,88 @@
using System;
namespace SourceFormatParser.Common
{
/// <summary>
/// Vector x/y/z (float)
/// Size: 12 bytes (4 bytes per axis)
/// </summary>
public struct SourceQAngle
{
// Members
public float x, y, z;
// Initialization
public SourceQAngle(float ix = 0.0f, float iy = 0.0f, float iz = 0.0f)
{
this.x = ix;
this.y = iy;
this.z = iz;
}
public static SourceQAngle Random(float minVal, float maxVal)
{
Random rand = new Random();
return new SourceQAngle(
ix: minVal + ((float)rand.NextDouble()) * (float)(maxVal - minVal),
iy: minVal + ((float)rand.NextDouble()) * (float)(maxVal - minVal),
iz: minVal + ((float)rand.NextDouble()) * (float)(maxVal - minVal)
);
}
// equality
public static bool operator ==(SourceQAngle v1, SourceQAngle v2) => v1.x == v2.x && v1.y == v2.y && v1.z == v2.z;
public static bool operator !=(SourceQAngle v1, SourceQAngle v2) => !(v1 == v2);
public override bool Equals(object obj) => this == (SourceQAngle)obj;
public override int GetHashCode() => base.GetHashCode();
// arithmetic operations
public static SourceQAngle operator +(SourceQAngle v1, SourceQAngle v2) => new SourceQAngle(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
public static SourceQAngle operator -(SourceQAngle v1, SourceQAngle v2) => new SourceQAngle(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
public static SourceQAngle operator *(SourceQAngle v, float s) => new SourceQAngle(v.x * s, v.y * s, v.z * s);
public static SourceQAngle operator /(SourceQAngle v, float fl)
{
if (fl == 0.0f)
return new SourceQAngle();
float oofl = 1.0f / fl;
return new SourceQAngle(v.x * oofl, v.y * oofl, v.z * oofl);
}
public float this[int i]
{
get
{
switch (i)
{
case 0:
return x;
case 1:
return y;
case 2:
return z;
}
throw new Exception("wrong index");
}
set
{
switch (i)
{
case 0:
x = value;
break;
case 1:
y = value;
break;
case 2:
z = value;
break;
}
}
}
// Get the vector's magnitude.
public float Length() => (float)Math.Sqrt(LengthSqr());
public float LengthSqr() => x * x + y * y + z * z;
public override string ToString() => $"{{{x}; {y}; {z}}}";
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 42f5749be91a85846b5abe45d8eab4fb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,134 @@
using System;
namespace SourceFormatParser.Common
{
/// <summary>
/// Quaternion x/y/z/w (float)
/// Size: 16 bytes (4 bytes per axis)
/// </summary>
public struct SourceQuaternion
{
// same data-layout as engine's vec4_t,
// which is a vec_t[4]=float[4]
public float x, y, z, w;
public SourceQuaternion(float ix, float iy, float iz, float iw)
{
//Init(ix, iy, iz, iw);
x = ix; y = iy; z = iz; w = iw;
}
public SourceQuaternion(SourceRadianEuler angle)
{
var t = new SourceQuaternion();
MathUtils.AngleQuaternion(angle, ref t);
this.x = t.x;
this.y = t.y;
this.z = t.z;
this.w = t.w;
}
public SourceQuaternion(SourceDegreeEuler angle)
{
SourceRadianEuler radians = new SourceRadianEuler(angle);
var t = new SourceQuaternion();
MathUtils.AngleQuaternion(radians, ref t);
this.x = t.x;
this.y = t.y;
this.z = t.z;
this.w = t.w;
}
void Init(float ix = 0.0f, float iy = 0.0f, float iz = 0.0f, float iw = 0.0f) { x = ix; y = iy; z = iz; w = iw; }
void Init(SourceVector vImaginaryPart, float flRealPart) { x = vImaginaryPart.x; y = vImaginaryPart.y; z = vImaginaryPart.z; w = flRealPart; }
public static bool operator ==(SourceQuaternion v1, SourceQuaternion v2) => v1.x == v2.x && v1.y == v2.y && v1.z == v2.z && v1.w == v2.w;
public static bool operator !=(SourceQuaternion v1, SourceQuaternion v2) => !(v1 == v2);
public override bool Equals(object obj) => this == (SourceQuaternion)obj;
public override int GetHashCode() => base.GetHashCode();
public SourceQuaternion Conjugate() { return new SourceQuaternion(-x, -y, -z, w); }
public SourceVector GetForward()
{
SourceVector vAxisX;
vAxisX.x = 1.0f - 2.0f * y * y - 2.0f * z * z;
vAxisX.y = 2.0f * x * y + 2.0f * w * z;
vAxisX.z = 2.0f * x * z - 2.0f * w * y;
return vAxisX;
}
public SourceVector GetLeft()
{
SourceVector vAxisY;
vAxisY.x = 2.0f * x * y - 2.0f * w * z;
vAxisY.y = 1.0f - 2.0f * x * x - 2.0f * z * z;
vAxisY.z = 2.0f * y * z + 2.0f * w * x;
return vAxisY;
}
public SourceVector GetUp()
{
SourceVector vAxisZ;
vAxisZ.x = 2.0f * x * z + 2.0f * w * y;
vAxisZ.y = 2.0f * y * z - 2.0f * w * x;
vAxisZ.z = 1.0f - 2.0f * x * x - 2.0f * y * y;
return vAxisZ;
}
public float RealPart() { return w; }
public SourceQAngle ToQAngle()
{
SourceQAngle anglesOut = new SourceQAngle();
MathUtils.QuaternionAngles(this, ref anglesOut);
return anglesOut;
}
public SourceMatrix3x4 ToMatrix()
{
SourceMatrix3x4 mat = new SourceMatrix3x4();
mat.InitFromQuaternion(this);
return mat;
}
// array access...
public float this[int i]
{
get
{
switch (i)
{
case 0: return x;
case 1: return y;
case 2: return z;
case 3: return w;
default: throw new Exception("wrong index [0..3]");
}
}
set
{
switch (i)
{
case 0:
x = value;
break;
case 1:
y = value;
break;
case 2:
z = value;
break;
case 3:
w = value;
break;
default:
throw new Exception("wrong index [0..3]");
}
}
}
public static SourceQuaternion operator +(SourceQuaternion q1, SourceQuaternion q2) => new SourceQuaternion(q1.x + q2.x, q1.y + q2.y, q1.z + q2.z, q1.w + q2.w);
public static SourceQuaternion operator -(SourceQuaternion q1, SourceQuaternion q2) => new SourceQuaternion(q1.x - q2.x, q1.y - q2.y, q1.z - q2.z, q1.w - q2.w);
public static SourceQuaternion Identity = new SourceQuaternion();
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f79c37491dea4d847806826d30312f7f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,76 @@
using System;
namespace SourceFormatParser.Common
{
/// <summary>
/// RadianEuler x/y/z (float)
/// Size: 12 bytes (4 bytes per axis)
/// </summary>
public class SourceRadianEuler
{
public SourceRadianEuler() { }
public SourceRadianEuler(float X, float Y, float Z) { x = X; y = Y; z = Z; }
public SourceRadianEuler(SourceQuaternion q)
{
var t = this;
MathUtils.QuaternionAngles(q, ref t);
this.x = t.x;
this.y = t.y;
this.z = t.z;
}
public SourceRadianEuler(SourceQAngle angles)
{
Init(angles.z * 3.14159265358979323846f / 180.0f,
angles.x * 3.14159265358979323846f / 180.0f,
angles.y * 3.14159265358979323846f / 180.0f);
}
public SourceRadianEuler(SourceDegreeEuler angles)
{
Init(MathUtils.DEG2RAD(angles.x), MathUtils.DEG2RAD(angles.y), MathUtils.DEG2RAD(angles.z));
}
// Initialization
public void Init(float ix = 0.0f, float iy = 0.0f, float iz = 0.0f) { x = ix; y = iy; z = iz; }
// conversion to qangle
public SourceQAngle ToQAngle() => new SourceQAngle(MathUtils.DEG2RAD(y), MathUtils.DEG2RAD(z), MathUtils.DEG2RAD(x));
public bool IsValid() { throw new NotImplementedException(); }
public void Invalidate() { throw new NotImplementedException(); }
public float Base() { return x; }
// array access...
public float this[int i]
{
get
{
switch (i)
{
case 0: return x;
case 1: return y;
case 2: return z;
default: throw new Exception("wrong index [0..2]");
}
}
set
{
switch (i)
{
case 0:
x = value;
break;
case 1:
y = value;
break;
case 2:
z = value;
break;
default:
throw new Exception("wrong index [0..2]");
}
}
}
public float x, y, z;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b270d4664974df54fb6bd34c1e015b9e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,169 @@
using System;
namespace SourceFormatParser.Common
{
/// <summary>
/// Vector x/y/z (float)
/// Size: 12 bytes (4 bytes per axis)
/// </summary>
public struct SourceVector
{
public float x, y, z;
public SourceVector(float ix = 0.0f, float iy = 0.0f, float iz = 0.0f)
{
this.x = ix;
this.y = iy;
this.z = iz;
}
// Initialization methods
public static SourceVector Random(float minVal, float maxVal)
{
Random rand = new Random();
return new SourceVector(
ix: minVal + ((float)rand.NextDouble()) * (float)(maxVal - minVal),
iy: minVal + ((float)rand.NextDouble()) * (float)(maxVal - minVal),
iz: minVal + ((float)rand.NextDouble()) * (float)(maxVal - minVal)
);
}
public void Zero() => x = y = z = 0.0f; ///< zero out a vector
// equality
public static bool operator ==(SourceVector v1, SourceVector v2) => v1.x == v2.x && v1.y == v2.y && v1.z == v2.z;
public static bool operator !=(SourceVector v1, SourceVector v2) => !(v1 == v2);
public override bool Equals(object obj) => this == (SourceVector)obj;
public override int GetHashCode() => base.GetHashCode();
// arithmetic operations
public static SourceVector operator +(SourceVector v1, SourceVector v2) => new SourceVector(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
public static SourceVector operator -(SourceVector v1, SourceVector v2) => new SourceVector(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
public static SourceVector operator *(SourceVector v1, SourceVector v2) => new SourceVector(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z);
public static SourceVector operator *(SourceVector v, float s) => new SourceVector(v.x * s, v.y * s, v.z * s);
public static SourceVector operator /(SourceVector v1, SourceVector v2)
{
return new SourceVector(
ix: v2.x != 0.0f ? v1.x / v2.x : 0f,
iy: v2.y != 0.0f ? v1.y / v2.y : 0f,
iz: v2.z != 0.0f ? v1.z / v2.z : 0f
);
}
public static SourceVector operator /(SourceVector v, float fl)
{
if (fl == 0.0f)
return new SourceVector();
float oofl = 1.0f / fl;
return new SourceVector(v.x * oofl, v.y * oofl, v.z * oofl);
}
public static SourceVector operator +(SourceVector v, float s) => new SourceVector(v.x + s, v.y + s, v.z + s); //< broadcast add
public static SourceVector operator -(SourceVector v, float s) => new SourceVector(v.x - s, v.y - s, v.z - s); //< broadcast sub
// negate the vector components
public void Negate()
{
x = -x;
y = -y;
z = -z;
}
// Get the vector's magnitude.
public float Length() => (float)Math.Sqrt(x * x + y * y + z * z);
// Get the vector's magnitude squared.
public float LengthSqr() => (x * x + y * y + z * z);
// return true if this vector is (0,0,0) within tolerance
public bool IsZero(float tolerance = 0.01f)
{
return x > -tolerance && x < tolerance &&
y > -tolerance && y < tolerance &&
z > -tolerance && z < tolerance;
}
public bool IsLengthGreaterThan(float val) => LengthSqr() > val * val;
public bool IsLengthLessThan(float val) => LengthSqr() < val * val;
// check if a vector is within the box defined by two other vectors // check a point against a box
public bool WithinAABox(SourceVector boxmin, SourceVector boxmax)
{
return (x >= boxmin.x) && (x <= boxmax.x) &&
(y >= boxmin.y) && (y <= boxmax.y) &&
(z >= boxmin.z) && (z <= boxmax.z);
}
// Get the distance from this vector to the other one.
public float DistTo(SourceVector vOther)
{
return new SourceVector(
ix: x - vOther.x,
iy: y - vOther.y,
iz: z - vOther.z
).Length();
}
// Get the distance from this vector to the other one squared.
// NJS: note, VC wasn't inlining it correctly in several deeply nested inlines due to being an 'out of line' inline.
// may be able to tidy this up after switching to VC7
public float DistToSqr(SourceVector vOther)
{
return new SourceVector(
ix: x - vOther.x,
iy: y - vOther.y,
iz: z - vOther.z
).LengthSqr();
}
// Multiply, add, and assign to this (ie: *this = a + b * scalar). This
// is about 12% faster than the actual vector equation (because it's done per-component
// rather than per-vector).
public void MulAdd(SourceVector a, SourceVector b, float scalar)
{
x = a.x + b.x * scalar;
y = a.y + b.y * scalar;
z = a.z + b.z * scalar;
}
// Dot product.
public float Dot(SourceVector vOther) => (x * vOther.x + y * vOther.y + z * vOther.z);
// 2d
public float Length2D() => (float)Math.Sqrt(Length2DSqr());
public float Length2DSqr() => (x * x + y * y);
// Cross product between two vectors.
public SourceVector Cross(SourceVector vOther)
{
return new SourceVector(
ix: y * vOther.z - z * vOther.y,
iy: z * vOther.x - x * vOther.z,
iz: x * vOther.y - y * vOther.x
);
}
// Returns a vector with the min or max in X, Y, and Z.
public SourceVector Min(SourceVector vOther)
{
return new SourceVector(x < vOther.x ? x : vOther.x,
y < vOther.y ? y : vOther.y,
z < vOther.z ? z : vOther.z);
}
public SourceVector Max(SourceVector vOther)
{
return new SourceVector(x > vOther.x ? x : vOther.x,
y > vOther.y ? y : vOther.y,
z > vOther.z ? z : vOther.z);
}
public override string ToString() => $"{{{x}; {y}; {z}}}";
public static SourceVector Empty => new SourceVector();
#if (UNITY)
public UnityEngine.Vector3 toVector3() => new UnityEngine.Vector3(x, y, z);
#else
public System.Numerics.Vector3 toVector3() => new System.Numerics.Vector3(x, y, z);
#endif
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cb2fb64018589c94bb555489a6bf3de0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,131 @@
using System;
namespace SourceFormatParser.Common
{
/// <summary>
/// Vector x/y (float)
/// Size: 8 bytes (4 bytes per axis).
/// Is Vector2D in Source Engine.
/// </summary>
public struct SourceVector2
{
public float x, y;
public SourceVector2(float ix = 0.0f, float iy = 0.0f)
{
this.x = ix;
this.y = iy;
}
// Initialization methods
public static SourceVector2 Random(float minVal, float maxVal)
{
Random rand = new Random();
return new SourceVector2(
ix: minVal + ((float)rand.NextDouble()) * (float)(maxVal - minVal),
iy: minVal + ((float)rand.NextDouble()) * (float)(maxVal - minVal)
);
}
// equality
public static bool operator ==(SourceVector2 v1, SourceVector2 v2) => v1.x == v2.x && v1.y == v2.y;
public static bool operator !=(SourceVector2 v1, SourceVector2 v2) => !(v1 == v2);
public override bool Equals(object obj) => this == (SourceVector2)obj;
public override int GetHashCode() => base.GetHashCode();
// arithmetic operations
public static SourceVector2 operator +(SourceVector2 v1, SourceVector2 v2) => new SourceVector2(v1.x + v2.x, v1.y + v2.y);
public static SourceVector2 operator -(SourceVector2 v1, SourceVector2 v2) => new SourceVector2(v1.x - v2.x, v1.y - v2.y);
public static SourceVector2 operator *(SourceVector2 v1, SourceVector2 v2) => new SourceVector2(v1.x * v2.x, v1.y * v2.y);
public static SourceVector2 operator *(SourceVector2 v, float s) => new SourceVector2(v.x * s, v.y * s);
public static SourceVector2 operator /(SourceVector2 v1, SourceVector2 v2)
{
return new SourceVector2(
ix: v2.x != 0.0f ? v1.x / v2.x : 0f,
iy: v2.y != 0.0f ? v1.y / v2.y : 0f
);
}
public static SourceVector2 operator /(SourceVector2 v, float fl)
{
if (fl == 0.0f)
return new SourceVector2();
float oofl = 1.0f / fl;
return new SourceVector2(v.x * oofl, v.y * oofl);
}
// negate the Vector2D components
public void Negate()
{
x = -x;
y = -y;
}
// Get the Vector2D's magnitude.
public float Length() => (float)Math.Sqrt(LengthSqr());
// Get the Vector2D's magnitude squared.
public float LengthSqr() => (x * x + y * y);
// return true if this vector is (0,0) within tolerance
public bool IsZero(float tolerance = 0.01f)
{
return x > -tolerance && x < tolerance &&
y > -tolerance && y < tolerance;
}
// Compare length.
public bool IsLengthGreaterThan(float val) => LengthSqr() > val * val;
public bool IsLengthLessThan(float val) => LengthSqr() < val * val;
// Get the distance from this Vector2D to the other one.
public float DistTo(SourceVector2 vOther)
{
return new SourceVector2(
ix: x - vOther.x,
iy: y - vOther.y
).Length();
}
// Get the distance from this Vector2D to the other one squared.
public float DistToSqr(SourceVector2 vOther)
{
return new SourceVector2(
ix: x - vOther.x,
iy: y - vOther.y
).LengthSqr();
}
// Multiply, add, and assign to this (ie: *this = a + b * scalar). This
// is about 12% faster than the actual Vector2D equation (because it's done per-component
// rather than per-Vector2D).
public void MulAdd(SourceVector2 a, SourceVector2 b, float scalar)
{
x = a.x + b.x * scalar;
y = a.y + b.y * scalar;
}
// Dot product.
public float Dot(SourceVector2 vOther) => (x * vOther.x + y * vOther.y);
// Returns a SourceVector2 with the min or max in X, Y, and Z.
public SourceVector2 Min(SourceVector2 vOther)
{
return new SourceVector2(x < vOther.x ? x : vOther.x,
y < vOther.y ? y : vOther.y);
}
public SourceVector2 Max(SourceVector2 vOther)
{
return new SourceVector2(x > vOther.x ? x : vOther.x,
y > vOther.y ? y : vOther.y);
}
public override string ToString() => $"{{{x}; {y}}}";
#if (UNITY)
public UnityEngine.Vector2 toVector2() => new UnityEngine.Vector2(x, y);
#else
public System.Numerics.Vector2 toVector2() => new System.Numerics.Vector2(x, y);
#endif
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 01a389a372b218e4badb9aa349210a72
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,25 @@
namespace SourceFormatParser.Common
{
/// <summary>
/// Vector x/y (int)
/// Size: 8 bytes (4 bytes per axis)
/// </summary>
public struct SourceVector2Int
{
public int x, y;
public SourceVector2Int(int x, int y)
{
this.x = x;
this.y = y;
}
public override string ToString() => $"{{{x}; {y}}}";
#if (UNITY)
public UnityEngine.Vector2 toVector2() => new UnityEngine.Vector2(x, y);
#else
public System.Numerics.Vector2 toVector2() => new System.Numerics.Vector2(x, y);
#endif
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ee4829acf0c1cc741af51994378390ae
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,25 @@
namespace SourceFormatParser.Common
{
/// <summary>
/// Vector x/y (short)
/// Size: 4 bytes (2 bytes per axis)
/// </summary>
public struct SourceVector2Short
{
public short x, y;
public SourceVector2Short(short x, short y)
{
this.x = x;
this.y = y;
}
public override string ToString() => $"{{{x}; {y}}}";
#if (UNITY)
public UnityEngine.Vector2 toVector2() => new UnityEngine.Vector2(x, y);
#else
public System.Numerics.Vector2 toVector2() => new System.Numerics.Vector2(x, y);
#endif
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 885618187896fa349b2d688f7f4e562d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,27 @@
namespace SourceFormatParser.Common
{
/// <summary>
/// Vector x/y/z/w (float)
/// Size: 16 bytes (4 bytes per axis)
/// </summary>
public struct SourceVector4
{
public float x, y, z, w;
public SourceVector4(float x, float y, float z, float w)
{
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
public override string ToString() => $"{{{x}; {y}; {z}; {w}}}";
#if (UNITY)
public UnityEngine.Vector4 toVector4() => new UnityEngine.Vector4(x, y, z, w);
#else
public System.Numerics.Vector4 toVector4() => new System.Numerics.Vector4(x, y, z, w);
#endif
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 90caee6c805baba4c9e44f68259e1f98
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,26 @@
namespace SourceFormatParser.Common
{
/// <summary>
/// Vector x/y/z (short)
/// Size: 6 bytes (2 bytes per axis)
/// </summary>
public struct SourceVectorShort
{
public short x, y, z;
public SourceVectorShort(short x, short y, short z)
{
this.x = x;
this.y = y;
this.z = z;
}
public override string ToString() => $"{{{x}; {y}; {z}}}";
#if (UNITY)
public UnityEngine.Vector3 toVector3() => new UnityEngine.Vector3(x, y, z);
#else
public System.Numerics.Vector3 toVector3() => new System.Numerics.Vector3(x, y, z);
#endif
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d9246da7cb8798c4db4f0fef0e99ee3e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net45" />
</packages>
@@ -0,0 +1,32 @@
fileFormatVersion: 2
guid: 9c82ed86e9a503847b7746c3248a744f
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 1
settings: {}
userData:
assetBundleName:
assetBundleVariant: