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; } }
public static VRTF CreateDefaultForSunShadow() { VRTF v = new Default(0, null); v.Layouts.Add(new ElementLayout(0, null, ElementFormat.Short4, 0, ElementUsage.Position, 0)); v.Stride = v.Layouts.Select(x => VRTF.ByteSizeFromFormat(x.Format)).Sum(); return(v); }
public static VRTF CreateDefaultForDropShadow() { VRTF v = new Default(0, null); v.Layouts.Add(new ElementLayout(0, null, ElementFormat.UShort4N, 0, ElementUsage.Position, 0)); v.Layouts.Add(new ElementLayout(0, null, ElementFormat.Short4_DropShadow, (byte)v.Layouts.Select(x => VRTF.ByteSizeFromFormat(x.Format)).Sum(), ElementUsage.UV, 0)); // above replaces following two lines, following discussion with Atavera on 25 May 2012. //v.Layouts.Add(new ElementLayout(0, null, ElementFormat.Short2, (byte)v.Layouts.Select(x => VRTF.ByteSizeFromFormat(x.Format)).Sum(), ElementUsage.UV, 0)); //v.Layouts.Add(new ElementLayout(0, null, ElementFormat.Short2, (byte)v.Layouts.Select(x => VRTF.ByteSizeFromFormat(x.Format)).Sum(), ElementUsage.UV, 1)); //-- //v.Layouts.Add(new ElementLayout(0, null, ElementFormat.ColorUByte4, (byte)v.Layouts.Select(x => VRTF.ByteSizeFromFormat(x.Format)).Sum(), ElementUsage.Normal, 0)); v.Stride = v.Layouts.Select(x => VRTF.ByteSizeFromFormat(x.Format)).Sum(); return(v); }
private static bool SetVertices(MemoryStream s, VRTF vrtf, IEnumerable <Vertex> vertices, float[] uvscales) { bool okay = true; PositionMinMax(vrtf, vertices); byte[] output = new byte[vrtf.Stride]; var position = vrtf.Layouts .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.Position); var normal = vrtf.Layouts .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.Normal); var uv = vrtf.Layouts .Where(x => x.Usage == VRTF.ElementUsage.UV) .ToArray(); var blendIndices = vrtf.Layouts .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.BlendIndex); var blendWeights = vrtf.Layouts .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.BlendWeight); var tangents = vrtf.Layouts .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.Tangent); var color = vrtf.Layouts .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.Colour); if (uvscales == null) { uvscales = defaultUVScales; } foreach (var v in vertices) { if (v.Position != null) { WritePositionData(v.Position, position, output, positionMax); } if (v.Normal != null) { WriteFloatData(v.Normal, normal, output); } for (int u = 0; u < uv.Length; u++) { var scale = u < uvscales.Length && uvscales[u] != 0 ? uvscales[u] : uvscales[0]; if (v.UV[u] != null) { if (!WriteUVData(v.UV[u], uv[u], output, scale)) { okay = false; } } } if (v.BlendIndices != null) { Array.Copy(v.BlendIndices, 0, output, blendIndices.Offset, VRTF.ByteSizeFromFormat(blendIndices.Format)); } if (v.BlendWeights != null) { WriteFloatData(v.BlendWeights, blendWeights, output); } if (v.Tangents != null) { WriteFloatData(v.Tangents, tangents, output); } if (v.Color != null) { WriteFloatData(v.Color, color, output); } s.Write(output, 0, output.Length); } s.Flush(); return(okay); }
//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; } }
public Vertex[] GetVertices(VRTF vrtf, long offset, int count, float[] uvscales) { long streamOffset = offset; Stream s = new MemoryStream(mBuffer); s.Seek(streamOffset, SeekOrigin.Begin); var position = vrtf.Layouts .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.Position); var normal = vrtf.Layouts .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.Normal); var uv = vrtf.Layouts .Where(x => x.Usage == VRTF.ElementUsage.UV) .ToArray(); var blendIndices = vrtf.Layouts .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.BlendIndex); var blendWeights = vrtf.Layouts .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.BlendWeight); var tangents = vrtf.Layouts .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.Tangent); var color = vrtf.Layouts .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.Colour); Vertex[] verts = new Vertex[count]; if (uvscales == null) { uvscales = new float[3]; } for (int i = 0; i < count; i++) { Vertex v = new Vertex(); byte[] data = new byte[vrtf.Stride]; s.Read(data, 0, vrtf.Stride); if (position != null) { float[] posPoints = new float[VRTF.FloatCountFromFormat(position.Format)]; ReadFloatData(data, position, ref posPoints); v.Position = posPoints; } if (normal != null) { float[] normPoints = new float[VRTF.FloatCountFromFormat(normal.Format)]; ReadFloatData(data, normal, ref normPoints); v.Normal = normPoints; } v.UV = new float[uv.Length][]; for (int j = 0; j < uv.Length; j++) { var u = uv[j]; float[] uvPoints = new float[VRTF.FloatCountFromFormat(u.Format)]; var scale = j < uvscales.Length && uvscales[j] != 0 ? uvscales[j] : uvscales[0]; ReadUVData(data, u, ref uvPoints, scale); v.UV[j] = uvPoints; } if (blendIndices != null) { byte[] blendIPoints = new byte[VRTF.ByteSizeFromFormat(blendIndices.Format)]; Array.Copy(data, blendIndices.Offset, blendIPoints, 0, blendIPoints.Length); v.BlendIndices = blendIPoints; } if (blendWeights != null) { float[] blendWPoints = new float[VRTF.FloatCountFromFormat(blendWeights.Format)]; ReadFloatData(data, blendWeights, ref blendWPoints); v.BlendWeights = blendWPoints; } if (tangents != null) { float[] tangentPoints = new float[VRTF.FloatCountFromFormat(tangents.Format)]; ReadFloatData(data, tangents, ref tangentPoints); v.Tangents = tangentPoints; } if (color != null) { float[] colorPoints = new float[VRTF.FloatCountFromFormat(color.Format)]; ReadFloatData(data, color, ref colorPoints); v.Color = colorPoints; } verts[i] = v; } return(verts); }