public static void ReadUVData(byte[] data, VRTF.ElementLayout layout, ref float[] output, float scale) { byte[] element = new byte[VRTF.ByteSizeFromFormat(layout.Format)]; Array.Copy(data, layout.Offset, element, 0, element.Length); switch (layout.Format) { case VRTF.ElementFormat.Short2: for (int i = 0; i < output.Length; i++) { output[i] += (float)BitConverter.ToInt16(element, i * sizeof(short)) * scale; } break; case VRTF.ElementFormat.Short4: for (int i = 0; i < output.Length; i++) { output[i] += (float)BitConverter.ToInt16(element, i * sizeof(short)) / short.MaxValue; } break; case VRTF.ElementFormat.Short4_DropShadow: for (int i = 0; i < output.Length - 1; i++) { output[i] += (float)BitConverter.ToInt16(element, i * sizeof(short)) / short.MaxValue; } output[output.Length - 1] += (float)BitConverter.ToInt16(element, (output.Length - 1) * sizeof(short)) / 511; break; default: ReadFloatData(data, layout, ref output); break; } }
private static bool WriteUVData(float[] input, VRTF.ElementLayout layout, byte[] output, float scale) { bool okay = true; switch (layout.Format) { case VRTF.ElementFormat.Short2: for (int i = 0; i < input.Length; i++) { if ((short)Math.Round(input[i] / scale) != (long)Math.Round(input[i] / scale)) { okay = false; } Array.Copy(BitConverter.GetBytes((short)Math.Round(input[i] / scale)), 0, output, layout.Offset + i * sizeof(short), sizeof(short)); } break; case VRTF.ElementFormat.Short4: for (int i = 0; i < input.Length; i++) { Array.Copy(BitConverter.GetBytes((short)Math.Round(input[i] * short.MaxValue)), 0, output, layout.Offset + i * sizeof(short), sizeof(short)); } break; case VRTF.ElementFormat.Short4_DropShadow: for (int i = 0; i < input.Length - 1; i++) { Array.Copy(BitConverter.GetBytes((short)Math.Round(input[i] * short.MaxValue)), 0, output, layout.Offset + i * sizeof(short), sizeof(short)); } Array.Copy(BitConverter.GetBytes((short)Math.Round(input[input.Length - 1] * 511)), 0, output, layout.Offset + (input.Length - 1) * sizeof(short), sizeof(short)); break; default: WriteFloatData(input, layout, output); break; } return(okay); }
private static void WritePositionData(float[] input, VRTF.ElementLayout layout, byte[] output, float max) { switch (layout.Format) { case VRTF.ElementFormat.UShort4N: //scalar = (max >= 1) ? 511 : (ulong)short.MaxValue; //-- could try "max < 1.0 / 512.0"? //ulong scalar = (ulong)(max < 1 ? short.MaxValue : 511); //scalar++; //2011-08-30 changed to fixed 512 as LoveseatDanishModern had problems ulong scalar = 512; for (int i = 0; i < input.Length; i++) { Array.Copy(BitConverter.GetBytes((short)Math.Round(input[i] * scalar)), 0, output, layout.Offset + i * sizeof(short), sizeof(short)); } Array.Copy(BitConverter.GetBytes((short)(scalar == 512 ? 0 : scalar - 1)), 0, output, layout.Offset + 3 * sizeof(short), sizeof(short)); break; default: WriteFloatData(input, layout, output); break; } }
private static void WriteFloatData(float[] input, VRTF.ElementLayout layout, byte[] output) { ulong scalar; double max; switch (layout.Format) { case VRTF.ElementFormat.Float1: case VRTF.ElementFormat.Float2: case VRTF.ElementFormat.Float3: case VRTF.ElementFormat.Float4: for (int i = 0; i < input.Length; i++) { Array.Copy(BitConverter.GetBytes(input[i]), 0, output, layout.Offset + i * sizeof(float), sizeof(float)); } break; case VRTF.ElementFormat.ColorUByte4: switch (layout.Usage) { case VRTF.ElementUsage.Colour: for (int i = 0; i < input.Length; i++) { output[layout.Offset + i] = (byte)Math.Round(input[i] * byte.MaxValue); } break; case VRTF.ElementUsage.BlendWeight: for (int i = 0; i < input.Length; i++) { output[layout.Offset + kColorUByte4Map[i]] = (byte)Math.Round(input[i] * byte.MaxValue); } break; case VRTF.ElementUsage.Normal: case VRTF.ElementUsage.Tangent: // -0.98828125 == (((0.5 + 1) / 128f) - 1) for (int i = 0; i < input.Length - 1; i++) { output[layout.Offset + 2 - i] = (byte)(input[i] < -0.98828125 ? 0 : (Math.Round((input[i] + 1) * 128) - 1)); } //-- // Wes: (signed char) bytes[0]=vert[2+vrtfp.offset[j]]; // (float) norms[0]=(float)bytes[0]; // norms[0]=(norms[0]<(float)0.0)?(norms[0]+(float)128.0):(norms[0]-(float)128.0); //?? //-- // input: +1 > 0 > -1 // map step1: +2 > +1 > 0 // map step2: 255 > 127.5 > 0 //for (int i = 0; i < input.Length - 1; i++) // output[layout.Offset + 2 - i] = (byte)Math.Round((input[i] + 1) * 127.5); if (input[input.Length - 1] == -1) { output[layout.Offset + 3] = 0; } else if (input[input.Length - 1] == 0) { output[layout.Offset + 3] = 127; } else if (input[input.Length - 1] == 1) { output[layout.Offset + 3] = 255; } else { System.Diagnostics.Debug.WriteLine(String.Format("Unexpected handedness {0}.", input[input.Length - 1])); } break; } break; case VRTF.ElementFormat.Short2: for (int i = 0; i < input.Length; i++) { Array.Copy(BitConverter.GetBytes((short)Math.Round(input[i] * short.MaxValue)), 0, output, layout.Offset + i * sizeof(short), sizeof(short)); } break; case VRTF.ElementFormat.Short4: max = Math.Ceiling(input.Max(x => Math.Abs(x))); scalar = (ulong)(max < 1 ? short.MaxValue : short.MaxValue / max); //scalar++; for (int i = 0; i < input.Length; i++) { Array.Copy(BitConverter.GetBytes((short)Math.Round(input[i] * scalar)), 0, output, layout.Offset + i * sizeof(short), sizeof(short)); } Array.Copy(BitConverter.GetBytes((short)(scalar /*- 1/**/)), 0, output, layout.Offset + 3 * sizeof(short), sizeof(short)); break; case VRTF.ElementFormat.UShort4N: max = Math.Ceiling(input.Max(x => Math.Abs(x))); scalar = (ulong)(max < 1.0 ? short.MaxValue : 512); //scalar++; for (int i = 0; i < input.Length; i++) { Array.Copy(BitConverter.GetBytes((short)Math.Round(input[i] * scalar)), 0, output, layout.Offset + i * sizeof(short), sizeof(short)); } Array.Copy(BitConverter.GetBytes((short)(scalar == 512 ? 0 : scalar /*- 1/**/)), 0, output, layout.Offset + 3 * sizeof(short), sizeof(short)); break; } }
//Currently not supported: //UByte4N, //Short2N, Short4N, UShort2N, //Dec3N, UDec3N, //Float16_2, Float16_4 public static void ReadFloatData(byte[] data, VRTF.ElementLayout layout, ref float[] output) { byte[] element = new byte[VRTF.ByteSizeFromFormat(layout.Format)]; Array.Copy(data, layout.Offset, element, 0, element.Length); float scalar; switch (layout.Format) { case VRTF.ElementFormat.Float1: case VRTF.ElementFormat.Float2: case VRTF.ElementFormat.Float3: case VRTF.ElementFormat.Float4: for (int i = 0; i < output.Length; i++) { output[i] += BitConverter.ToSingle(element, i * sizeof(float)); } break; case VRTF.ElementFormat.ColorUByte4: switch (layout.Usage) { case VRTF.ElementUsage.Colour: for (int i = 0; i < output.Length; i++) { output[i] += element[i] / (float)byte.MaxValue; } break; case VRTF.ElementUsage.BlendWeight: for (int i = 0; i < output.Length; i++) { output[i] += element[kColorUByte4Map[i]] / (float)byte.MaxValue; } break; case VRTF.ElementUsage.Normal: case VRTF.ElementUsage.Tangent: for (int i = 0; i < output.Length - 1; i++) { output[i] += element[2 - i] == 0 ? -1 : (((element[2 - i] + 1) / 128f) - 1); } //-- // Wes: (signed char) bytes[0]=vert[2+vrtfp.offset[j]]; // (float) norms[0]=(float)bytes[0]; // norms[0]=(norms[0]<(float)0.0)?(norms[0]+(float)128.0):(norms[0]-(float)128.0); //??? //-- // input: 255 > 128 > 127 > 0 // map step1: +2 > 0 // map step2: +1 > -1 //for (int i = 0; i < output.Length - 1; i++) // output[i] += (element[2 - i] / 127.5f) - 1f; switch (element[3]) { case 0: output[output.Length - 1] = -1f; break; // -1 determinant case 127: output[output.Length - 1] = 0f; break; // There is no determinant case 255: output[output.Length - 1] = +1f; break; // +1 determinant default: System.Diagnostics.Debug.WriteLine(String.Format("Unexpected handedness {0}.", element[3])); break; } break; } break; case VRTF.ElementFormat.Short2: for (int i = 0; i < output.Length; i++) { output[i] += BitConverter.ToInt16(element, i * sizeof(short)) / (float)short.MaxValue; } break; case VRTF.ElementFormat.Short4: scalar = BitConverter.ToUInt16(element, 3 * sizeof(short)); if (scalar == 0) { scalar = short.MaxValue; } //scalar++; for (int i = 0; i < output.Length; i++) { output[i] += BitConverter.ToInt16(element, i * sizeof(short)) / scalar; } break; case VRTF.ElementFormat.UShort4N: scalar = BitConverter.ToUInt16(element, 3 * sizeof(ushort)); if (scalar == 0) { scalar = 511; } //scalar++; for (int i = 0; i < output.Length; i++) { output[i] += BitConverter.ToInt16(element, i * sizeof(short)) / scalar; } break; } }