/// <summary> /// Decodes a 1-bit alpha map into a list of byte values. The resulting list will be values of either 0 or 255. /// </summary> /// <param name="inData">The binary data.</param> /// <returns>The decoded map.</returns> private static List <byte> Decode1BitAlpha(byte[] inData) { var alphaValues = new List <byte>(); foreach (var dataByte in inData) { // The alpha value is stored per-bit in the byte (8 alpha values per byte) for (byte i = 0; i < 8; ++i) { var alphaBit = (byte)ExtendedMath.Map((dataByte >> (7 - i)) & 0x01, 0, 1, 0, 255); // At this point, alphaBit will be either 0 or 1. Map this to 0 or 255. if (alphaBit > 0) { alphaValues.Add(255); } else { alphaValues.Add(0); } } } return(alphaValues); }
public void TestExtentedMathRound() { Assert.AreEqual(ExtendedMath.Round(2.1, 2), 2.1, eps); Assert.AreEqual(ExtendedMath.Round(2.11, 2), 2.11, eps); Assert.AreEqual(ExtendedMath.Round(2.123, 2), 2.12, eps); Assert.AreEqual(ExtendedMath.Round(2.125, 2), 2.12, eps); Assert.AreEqual(ExtendedMath.Round(2.1251, 2), 2.13, eps); }
/// <summary> /// Get the bounding sphere of this entity. /// </summary> /// <param name="parent">Parent node that's currently drawing this entity.</param> /// <param name="localTransformations">Local transformations from the direct parent node.</param> /// <param name="worldTransformations">World transformations to apply on this entity (this is what you should use to draw this entity).</param> /// <returns>Bounding box of the entity.</returns> protected override BoundingSphere CalcBoundingSphere(Node parent, ref Matrix localTransformations, ref Matrix worldTransformations) { // get bounding sphere in local space BoundingSphere modelBoundingSphere = _localBoundingSphere; // apply transformations on bounding sphere Vector3 scale = ExtendedMath.GetScale(ref worldTransformations); modelBoundingSphere.Radius *= System.Math.Max(scale.X, System.Math.Max(scale.Y, scale.Z)); modelBoundingSphere.Center = Vector3.Transform(modelBoundingSphere.Center, worldTransformations); return(modelBoundingSphere); }
/// <summary> /// Move the cannibal on x/z. /// </summary> /// <param name="input">input x/z between 0 and 1 </param> public void GroundMove(Vector2 input) { Vector3 input3D = new Vector3(input.x, 0, input.y); input3D = ExtendedMath.ProjectVectorOnPlane(m_characterControllerExt.GroundNormal, input3D); input3D.Normalize(); m_characterControllerExt.velocity.x = m_maxRunSpeed * input3D.x; m_characterControllerExt.velocity.z = m_maxRunSpeed * input3D.z; if (m_characterControllerExt.velocity.magnitude > m_maxRunSpeed) { m_characterControllerExt.velocity = m_characterControllerExt.velocity.normalized * m_maxRunSpeed; } }
/// <summary> /// Decodes a compressed 4-bit alpha map into a list of byte values. /// </summary> /// <param name="inData">The binary data.</param> /// <returns>The decoded map.</returns> private static List <byte> Decode4BitAlpha(byte[] inData) { var alphaValues = new List <byte>(); foreach (var alphaByte in inData) { // The alpha value is stored as half a byte (2 alpha values per byte) // Extract these two values and map them to a byte size (4 bits can hold 0 - 15 alpha) var alphaValue1 = (byte)ExtendedMath.Map(alphaByte >> 4, 0, 15, 0, 255); var alphaValue2 = (byte)ExtendedMath.Map(alphaByte & 0x0F, 0, 15, 0, 255); alphaValues.Add(alphaValue1); alphaValues.Add(alphaValue2); } return(alphaValues); }
/// <summary> /// Encodes the alpha data of the provided image as a packed byte array of alpha values. /// 2 alpha values are stored in each byte as a uint4_t integer value. /// </summary> /// <returns>The bit alpha.</returns> /// <param name="inMap">In map.</param> private List <byte> Encode4BitAlpha(Image <Rgba32> inMap) { var alphaValues = new List <byte>(); for (var y = 0; y < inMap.Height; ++y) { for (var x = 0; x < inMap.Width; ++x) { alphaValues.Add(inMap[x, y].A); } } var packedAlphaValues = new List <byte>(); for (var i = 0; i < alphaValues.Count; i += 2) { var packedAlphaValue = default(byte); for (var j = 0; j < 2; ++j) { byte alphaValue; if ((i + j) < alphaValues.Count) { alphaValue = alphaValues[i + j]; } else { alphaValue = 0; } // Pack the alpha value into the byte if (j == 0) { // Pack into the first four bits packedAlphaValue |= (byte)(ExtendedMath.Map(alphaValue, 0, 255, 0, 15) << 4); } else { // Pack into the last four bits packedAlphaValue |= (byte)ExtendedMath.Map(alphaValue & 0x0F, 0, 255, 0, 15); } } packedAlphaValues.Add(packedAlphaValue); } return(packedAlphaValues); }
/// <summary> /// Encodes the alpha data of the provided image as a packed byte array of alpha values. /// 2 alpha values are stored in each byte as a uint4_t integer value. /// </summary> /// <returns>The bit alpha.</returns> /// <param name="inMap">In map.</param> private List <byte> Encode4BitAlpha(Bitmap inMap) { List <byte> alphaValues = new List <byte>(); for (int y = 0; y < inMap.Height; ++y) { for (int x = 0; x < inMap.Width; ++x) { alphaValues.Add(inMap.GetPixel(x, y).A); } } List <byte> packedAlphaValues = new List <byte>(); for (int i = 0; i < alphaValues.Count; i += 2) { byte packedAlphaValue = new byte(); for (int j = 0; j < 2; ++j) { byte alphaValue; if ((i + j) < alphaValues.Count) { alphaValue = alphaValues[i + j]; } else { alphaValue = 0; } // Pack the alpha value into the byte if (j == 0) { // Pack into the first four bits packedAlphaValue |= (byte)(ExtendedMath.Map(alphaValue, 0, 255, 0, 15) << 4); } else { // Pack into the last four bits packedAlphaValue |= (byte)ExtendedMath.Map(alphaValue & 0x0F, 0, 255, 0, 15); } } packedAlphaValues.Add(packedAlphaValue); } return(packedAlphaValues); }
public IPolesCoefficients CalculateAnalog(int order, double ripple) { if (order < 1) { throw new ArgumentOutOfRangeException(nameof(order), @"Order must be greater than 0."); } if (ripple >= 0.0d) { throw new ArgumentOutOfRangeException(nameof(ripple), @"Ripple must be greater than 0."); } var z = new List <Complex>(); var eps = Math.Sqrt(Math.Pow(10.0d, 0.1d * ripple) - 1.0d); var mu = 1.0d / order * ExtendedMath.ArcSinh(1 / eps); var p = new List <Complex>(); var start = 0; for (var i = 0; i < order; i++, start += 2) { var theta = start * Math.PI / (2.0 * order); p.Add(-Complex.Sinh(mu + theta * new Complex(0.0d, 1.0d))); } var k = p.Negative().Product().Real; if (order % 2 == 0) { k = k / Math.Sqrt(1 + eps * eps); } return(this.polesCoefficientsFactory.Build(k, p, z)); }
/// <summary> /// Compresses in input bitmap into a single mipmap at the specified mipmap level, where a mip level is a /// bisection of the resolution. /// For instance, a mip level of 2 applied to a 64x64 image would produce an image with a resolution of 16x16. /// This function expects the mipmap level to be reasonable (i.e, not a level which would produce a mip smaller /// than 1x1). /// </summary> /// <returns>The image.</returns> /// <param name="inImage">Image.</param> /// <param name="mipLevel">Mip level.</param> private byte[] CompressImage(Image <Rgba32> inImage, uint mipLevel) { var targetXRes = GetLevelAdjustedResolutionValue(GetResolution().X, mipLevel); var targetYRes = GetLevelAdjustedResolutionValue(GetResolution().Y, mipLevel); var colourData = new List <byte>(); var alphaData = new List <byte>(); using (var resizedImage = ResizeImage(inImage, (int)targetXRes, (int)targetYRes)) { if (Header.CompressionType == TextureCompressionType.Palettized) { // Generate the colour data for (var y = 0; y < targetYRes; ++y) { for (var x = 0; x < targetXRes; ++x) { var nearestColor = FindClosestMatchingColor(resizedImage[x, y]); var paletteIndex = (byte)_palette.IndexOf(nearestColor); colourData.Add(paletteIndex); } } // Generate the alpha data if (GetAlphaBitDepth() > 0) { if (GetAlphaBitDepth() == 1) { // We're going to be attempting to map 8 pixels on each X iteration for (var y = 0; y < targetYRes; ++y) { for (var x = 0; x < targetXRes; x += 8) { // The alpha value is stored per-bit in the byte (8 alpha values per byte) byte alphaByte = 0; for (byte i = 0; (i < 8) && (i < targetXRes); ++i) { var pixelAlpha = resizedImage[x + i, y].A; if (pixelAlpha > 0) { pixelAlpha = 1; } // Shift the value into the correct position in the byte pixelAlpha = (byte)(pixelAlpha << (7 - i)); alphaByte = (byte)(alphaByte | pixelAlpha); } alphaData.Add(alphaByte); } } } else if (GetAlphaBitDepth() == 4) { // We're going to be attempting to map 2 pixels on each X iteration for (var y = 0; y < targetYRes; ++y) { for (var x = 0; x < targetXRes; x += 2) { // The alpha value is stored as half a byte (2 alpha values per byte) // Extract these two values and map them to a byte size (4 bits can hold 0 - 15 // alpha) byte alphaByte = 0; for (byte i = 0; (i < 2) && (i < targetXRes); ++i) { // Get the value from the image var pixelAlpha = resizedImage[x + i, y].A; // Map the value to a 4-bit integer pixelAlpha = (byte)ExtendedMath.Map(pixelAlpha, 0, 255, 0, 15); // Shift the value to the upper bits on the first iteration, and leave it where // it is on the second one pixelAlpha = (byte)(pixelAlpha << (4 * (1 - i))); alphaByte = (byte)(alphaByte | pixelAlpha); } alphaData.Add(alphaByte); } } } else if (GetAlphaBitDepth() == 8) { for (var y = 0; y < targetYRes; ++y) { for (var x = 0; x < targetXRes; ++x) { // The alpha value is stored as a whole byte var alphaValue = resizedImage[x, y].A; alphaData.Add(alphaValue); } } } } else { // The map is fully opaque for (var y = 0; y < targetYRes; ++y) { for (var x = 0; x < targetXRes; ++x) { alphaData.Add(255); } } } } else if (Header.CompressionType == TextureCompressionType.DXTC) { using (var rgbaStream = new MemoryStream()) { using (var bw = new BinaryWriter(rgbaStream)) { for (var y = 0; y < targetYRes; ++y) { for (var x = 0; x < targetXRes; ++x) { bw.Write(resizedImage[x, y].R); bw.Write(resizedImage[x, y].G); bw.Write(resizedImage[x, y].B); bw.Write(resizedImage[x, y].A); } } // Finish writing the data bw.Flush(); var rgbaBytes = rgbaStream.ToArray(); var squishOptions = SquishOptions.DXT1; if (Header.PixelFormat == BLPPixelFormat.DXT3) { squishOptions = SquishOptions.DXT3; } else if (Header.PixelFormat == BLPPixelFormat.DXT5) { squishOptions = SquishOptions.DXT5; } // TODO: Implement squish compression colourData = new List <byte> ( SquishCompression.CompressImage ( rgbaBytes, (int)targetXRes, (int)targetYRes, squishOptions ) ); } } } else if (Header.CompressionType == TextureCompressionType.Uncompressed) { using (var argbStream = new MemoryStream()) { using (var bw = new BinaryWriter(argbStream)) { for (var y = 0; y < targetYRes; ++y) { for (var x = 0; x < targetXRes; ++x) { bw.Write(resizedImage[x, y].A); bw.Write(resizedImage[x, y].R); bw.Write(resizedImage[x, y].G); bw.Write(resizedImage[x, y].B); } } // Finish writing the data bw.Flush(); var argbBytes = argbStream.ToArray(); colourData = new List <byte>(argbBytes); } } } } // After compression of the data, merge the color data and alpha data var compressedMipMap = new byte[colourData.Count + alphaData.Count]; Buffer.BlockCopy(colourData.ToArray(), 0, compressedMipMap, 0, colourData.ToArray().Length); Buffer.BlockCopy ( alphaData.ToArray(), 0, compressedMipMap, colourData.ToArray().Length, alphaData.ToArray().Length ); return(compressedMipMap); }
public void TestExtendeMathFloor() { Assert.AreEqual(ExtendedMath.Floor(2.1, 2), 2.1, eps); Assert.AreEqual(ExtendedMath.Floor(1.2233, 2), 1.22, eps); Assert.AreEqual(ExtendedMath.Floor(1.223, 3), 1.223, eps); }
public void TestExtendedMathCeiling() { Assert.AreEqual(ExtendedMath.Ceiling(2.1, 2), 2.1, eps); Assert.AreEqual(ExtendedMath.Ceiling(1.2233, 2), 1.23, eps); Assert.AreEqual(ExtendedMath.Ceiling(1.22, 2), 1.22, eps); }
public void TestDecPowerNegative() { Assert.AreEqual(ExtendedMath.DecPowerNegative(2, 2), 0.02); Assert.AreEqual(ExtendedMath.DecPowerNegative(2.1, 3), 0.0021, eps); }
public void TestDecPowerPositive() { Assert.AreEqual(ExtendedMath.DecPowerPositive(2, 2), 200); Assert.AreEqual(ExtendedMath.DecPowerPositive(1.2223, 2), 122.23, eps); }