public MeshVertex(CoordinateF location, IEnumerable<BoneWeighting> boneWeightings, float textureU, float textureV) { Location = location; BoneWeightings = boneWeightings; TextureU = textureU; TextureV = textureV; }
public MeshVertex(CoordinateF location,Bone bone, float textureU, float textureV) { Location = location; BoneWeightings = new List<BoneWeighting> {new BoneWeighting(bone, 1)}; TextureU = textureU; TextureV = textureV; }
public MatrixF Translate(CoordinateF translation) { return(new MatrixF(Values[0], Values[1], Values[2], Values[3], Values[4], Values[5], Values[6], Values[7], Values[8], Values[9], Values[10], Values[11], Values[12] + translation.X, Values[13] + translation.Y, Values[14] + translation.Z, Values[15])); }
public CoordinateF Rotate(CoordinateF coord) { // http://content.gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation var q = new QuaternionF(coord.Normalise(), 0); var temp = q * Conjugate(); return((this * temp).Vector); }
public bool EquivalentTo(CoordinateF test, float delta = 0.0001f) { var xd = Math.Abs(X - test.X); var yd = Math.Abs(Y - test.Y); var zd = Math.Abs(Z - test.Z); return((xd < delta) && (yd < delta) && (zd < delta)); }
public CoordinateF Cross(CoordinateF that) { var xv = (Y * that.Z) - (Z * that.Y); var yv = (Z * that.X) - (X * that.Z); var zv = (X * that.Y) - (Y * that.X); return(new CoordinateF(xv, yv, zv)); }
public static MatrixF Translation(CoordinateF translation) { var m = Identity; m.Values[12] = translation.X; m.Values[13] = translation.Y; m.Values[14] = translation.Z; return(m); }
public static MatrixF Scale(CoordinateF scale) { var m = Identity; m.Values[0] = scale.X; m.Values[5] = scale.Y; m.Values[10] = scale.Z; return(m); }
public bool Equals(CoordinateF other) { if (ReferenceEquals(null, other)) { return(false); } if (ReferenceEquals(this, other)) { return(true); } return(EquivalentTo(other)); }
public static MatrixF Rotation(CoordinateF axis, float angle) { var cos = (float)Math.Cos(-angle); var sin = (float)Math.Sin(-angle); var t = 1f - cos; axis = axis.Normalise(); return(new MatrixF(t * axis.X * axis.X + cos, t * axis.X * axis.Y - sin * axis.Z, t * axis.X * axis.Z + sin * axis.Y, 0, t * axis.X * axis.Y + sin * axis.Z, t * axis.Y * axis.Y + cos, t * axis.Y * axis.Z - sin * axis.X, 0, t * axis.X * axis.Z - sin * axis.Y, t * axis.Y * axis.Z + sin * axis.X, t * axis.Z * axis.Z + cos, 0, 0, 0, 0, 1)); }
public Bone(int boneIndex, int parentIndex, Bone parent, string name, CoordinateF defaultPosition, CoordinateF defaultAngles, CoordinateF defaultPositionScale, CoordinateF defaultAnglesScale) { BoneIndex = boneIndex; ParentIndex = parentIndex; Parent = parent; Name = name; DefaultPosition = defaultPosition; DefaultAngles = defaultAngles; DefaultPositionScale = defaultPositionScale; DefaultAnglesScale = defaultAnglesScale; Transform = QuaternionF.EulerAngles(DefaultAngles).GetMatrix().Translate(defaultPosition); if (parent != null) Transform *= parent.Transform; }
public static QuaternionF EulerAngles(CoordinateF angles) { // http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternionF/index.htm angles = angles / 2; var sy = (float)Math.Sin(angles.Z); var sp = (float)Math.Sin(angles.Y); var sr = (float)Math.Sin(angles.X); var cy = (float)Math.Cos(angles.Z); var cp = (float)Math.Cos(angles.Y); var cr = (float)Math.Cos(angles.X); return(new QuaternionF(sr * cp * cy - cr * sp * sy, cr * sp * cy + sr * cp * sy, cr * cp * sy - sr * sp * cy, cr * cp * cy + sr * sp * sy)); }
public CoordinateF ComponentDivide(CoordinateF c) { if (Math.Abs(c.X - 0) < 0.0001) { c.X = 1; } if (Math.Abs(c.Y - 0) < 0.0001) { c.Y = 1; } if (Math.Abs(c.Z - 0) < 0.0001) { c.Z = 1; } return(new CoordinateF(X / c.X, Y / c.Y, Z / c.Z)); }
public MatrixF Translate(CoordinateF translation) { return new MatrixF(Values[0], Values[1], Values[2], Values[3], Values[4], Values[5], Values[6], Values[7], Values[8], Values[9], Values[10], Values[11], Values[12] + translation.X, Values[13] + translation.Y, Values[14] + translation.Z, Values[15]); }
public void ReadData(BinaryReader br) { var delta = (Flags & StudioAnimDelta) > 0; if ((Flags & StudioAnimRawrot) > 0) { // WTF is this messy format :| // 48-bit Quaternion: 16-bit x, 16-bit y, 15-bit z, 1 bit to flag if w is negative // Convert into real quaternion with the algorithm below (taken from compressed_vector.h) int x = br.ReadUInt16(); int y = br.ReadUInt16(); var temp = br.ReadUInt16(); var z = temp & 0x7FFF; // Get the last 15 bits from the short var isWneg = (temp & 0x8000) > 0; // The first bit is the boolean value var w = (isWneg ? -1 : 1) * (float) Math.Sqrt(1 - x * x - y * y - z * z); FixedQuaternion = new QuaternionF((x - Half) / Half, (y - Half) / Half, (z - Quarter) / Quarter, w); } if ((Flags & StudioAnimRawpos) > 0) { // What's this? A custom made, 16-bit floating point implementation? WHAT DID I DO TO DESERVE THIS??? var bytes = br.ReadBytes(6); // Wait a minute..... var x = OpenTK.Half.FromBytes(bytes, 0).ToSingle(); var y = OpenTK.Half.FromBytes(bytes, 2).ToSingle(); var z = OpenTK.Half.FromBytes(bytes, 4).ToSingle(); // Ha ha, screw you, custom floating-point implementation! Thanks, OpenTK! FixedPosition = new CoordinateF(x, y, z); } if ((Flags & StudioAnimAnimrot) > 0) { // Why is this so painful :( // Read the per-frame data using RLE, just like GoldSource models var startPos = br.BaseStream.Position; var offsets = br.ReadShortArray(3); var endPos = br.BaseStream.Position; var rotFrames = new List<float[]>(); for (var i = 0; i < NumFrames; i++) rotFrames.Add(new float[] {0, 0, 0}); for (var i = 0; i < 3; i++) { if (offsets[i] == 0) continue; br.BaseStream.Position = startPos + offsets[i]; var values = ReadRLEEncodedAnimationFrameValues(br, NumFrames); for (var f = 0; f < values.Count; f++) { rotFrames[f][i] =+ values[f]; if (f > 0 && delta) rotFrames[f][i] += values[f - 1]; } } FrameAngles.AddRange(rotFrames.Select(x => new CoordinateF(x[0], x[1], x[2]))); br.BaseStream.Position = endPos; } if ((Flags & StudioAnimAnimpos) > 0) { // Same as above, except for the position coordinate var startPos = br.BaseStream.Position; var offsets = br.ReadShortArray(3); var endPos = br.BaseStream.Position; var posFrames = new List<float[]>(); for (var i = 0; i < NumFrames; i++) posFrames.Add(new float[] { 0, 0, 0 }); for (var i = 0; i < 3; i++) { if (offsets[i] == 0) continue; br.BaseStream.Position = startPos + offsets[i]; var values = ReadRLEEncodedAnimationFrameValues(br, NumFrames); for (var f = 0; f < values.Count; f++) { posFrames[f][i] = +values[f]; if (f > 0 && delta) posFrames[f][i] += values[f - 1]; } } FramePositions.AddRange(posFrames.Select(x => new CoordinateF(x[0], x[1], x[2]))); br.BaseStream.Position = endPos; } }
public static void WriteCoordinateF(this BinaryWriter bw, CoordinateF c) { bw.Write(c.X); bw.Write(c.Y); bw.Write(c.Z); }
public CoordinateF ComponentMultiply(CoordinateF c) { return new CoordinateF(X * c.X, Y * c.Y, Z * c.Z); }
public static MatrixF Translation(CoordinateF translation) { var m = Identity; m.Values[12] = translation.X; m.Values[13] = translation.Y; m.Values[14] = translation.Z; return m; }
public float Dot(CoordinateF c) { return((X * c.X) + (Y * c.Y) + (Z * c.Z)); }
public QuaternionF(float x, float y, float z, float w) { Vector = new CoordinateF(x, y, z); Scalar = w; }
public CoordinateF ComponentMultiply(CoordinateF c) { return(new CoordinateF(X * c.X, Y * c.Y, Z * c.Z)); }
public VVDPoint(float[] boneWeights, byte[] bones, int numBones, CoordinateF position, CoordinateF normal, float textureS, float textureT) { BoneWeights = boneWeights; Bones = bones; NumBones = numBones; Position = position; Normal = normal; TextureS = textureS; TextureT = textureT; }
public static QuaternionF AxisAngle(CoordinateF axis, float angle) { return(Math.Abs(axis.VectorMagnitude()) < 0.0001 ? Identity : new QuaternionF(axis.Normalise() * (float)Math.Sin(angle / 2), (float)Math.Cos(angle / 2)).Normalise()); }
private static void ReadAnimationGoldsource(BinaryReader br, DataStructures.Models.Model model, int numframes) { var anim = new Animation(); // Add all the empty frames for (var i = 0; i < numframes; i++) anim.Frames.Add(new AnimationFrame()); // Now we have a reader with the position at the start of the animation data // First up is the list of offset indexes for the data, one for each bone in the model. // Bones are already loaded up, so loop through those. foreach (var bone in model.Bones) { var offsetPos = br.BaseStream.Position; var offsets = br.ReadShortArray(6); var restorePoint = br.BaseStream.Position; var position = bone.DefaultPosition; var angles = bone.DefaultAngles; var boneFrames = new List<float[]>(); for (var i = 0; i < numframes; i++) boneFrames.Add(new float[] {0, 0, 0, 0, 0, 0}); for (var i = 0; i < 6; i++) // For each offset [X, Y, Z, XR, YR, ZR] { if (offsets[i] <= 0) continue; br.BaseStream.Position = offsetPos + offsets[i]; var values = ReadRLEEncodedAnimationFrameValues(br, numframes); for (var f = 0; f < numframes; f++) { boneFrames[f][i] += values[f]; } } for (var f = 0; f < numframes; f++) { var frame = boneFrames[f]; var fpos = new CoordinateF(frame[0], frame[1], frame[2]).ComponentMultiply(bone.DefaultPositionScale) + bone.DefaultPosition; var fang = new CoordinateF(frame[3], frame[4], frame[5]).ComponentMultiply(bone.DefaultAnglesScale) + bone.DefaultAngles; anim.Frames[f].Bones.Add(new BoneAnimationFrame(bone, fpos, QuaternionF.EulerAngles(fang))); } br.BaseStream.Position = restorePoint; } model.Animations.Add(anim); }
public bool EquivalentTo(CoordinateF test, float delta = 0.0001f) { var xd = Math.Abs(X - test.X); var yd = Math.Abs(Y - test.Y); var zd = Math.Abs(Z - test.Z); return (xd < delta) && (yd < delta) && (zd < delta); }
public bool Equals(CoordinateF other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; return EquivalentTo(other); }
public float Dot(CoordinateF c) { return ((X * c.X) + (Y * c.Y) + (Z * c.Z)); }
public CoordinateF Cross(CoordinateF that) { var xv = (Y * that.Z) - (Z * that.Y); var yv = (Z * that.X) - (X * that.Z); var zv = (X * that.Y) - (Y * that.X); return new CoordinateF(xv, yv, zv); }
public QuaternionF(CoordinateF vector, float scalar) { Vector = vector; Scalar = scalar; }
public BoneAnimationFrame(Bone bone, CoordinateF position, QuaternionF angles) { Bone = bone; Position = position; Angles = angles; }
private static void GLCoordinate(Vertex v, CoordinateF normal, bool texture) { if (texture) { GL.TexCoord2(v.DTextureU, v.DTextureV); } GL.Normal3(normal.X, normal.Y, normal.Z); GLCoordinate(v.Location); }
public static QuaternionF AxisAngle(CoordinateF axis, float angle) { return Math.Abs(axis.VectorMagnitude()) < 0.0001 ? Identity : new QuaternionF(axis.Normalise() * (float)Math.Sin(angle / 2), (float)Math.Cos(angle / 2)).Normalise(); }
public static QuaternionF EulerAngles(CoordinateF angles) { // http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternionF/index.htm angles = angles / 2; var sy = (float) Math.Sin(angles.Z); var sp = (float) Math.Sin(angles.Y); var sr = (float) Math.Sin(angles.X); var cy = (float) Math.Cos(angles.Z); var cp = (float) Math.Cos(angles.Y); var cr = (float) Math.Cos(angles.X); return new QuaternionF(sr * cp * cy - cr * sp * sy, cr * sp * cy + sr * cp * sy, cr * cp * sy - sr * sp * cy, cr * cp * cy + sr * sp * sy); }
public static MatrixF Scale(CoordinateF scale) { var m = Identity; m.Values[0] = scale.X; m.Values[5] = scale.Y; m.Values[10] = scale.Z; return m; }
public static MatrixF Rotation(CoordinateF axis, float angle) { var cos = (float) Math.Cos(-angle); var sin = (float) Math.Sin(-angle); var t = 1f - cos; axis = axis.Normalise(); return new MatrixF(t * axis.X * axis.X + cos, t * axis.X * axis.Y - sin * axis.Z, t * axis.X * axis.Z + sin * axis.Y, 0, t * axis.X * axis.Y + sin * axis.Z, t * axis.Y * axis.Y + cos, t * axis.Y * axis.Z - sin * axis.X, 0, t * axis.X * axis.Z - sin * axis.Y, t * axis.Y * axis.Z + sin * axis.X, t * axis.Z * axis.Z + cos, 0, 0, 0, 0, 1); }
public CoordinateF Rotate(CoordinateF coord) { // http://content.gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation var q = new QuaternionF(coord.Normalise(), 0); var temp = q * Conjugate(); return (this * temp).Vector; }
public static CoordinateF[] ReadCoordinateFArray(this BinaryReader br, int num) { var arr = new CoordinateF[num]; for (var i = 0; i < num; i++) arr[i] = br.ReadCoordinateF(); return arr; }
public CoordinateF ComponentDivide(CoordinateF c) { if (Math.Abs(c.X - 0) < 0.0001) c.X = 1; if (Math.Abs(c.Y - 0) < 0.0001) c.Y = 1; if (Math.Abs(c.Z - 0) < 0.0001) c.Z = 1; return new CoordinateF(X / c.X, Y / c.Y, Z / c.Z); }