public static VRTF CreateDefaultForDropShadow() { VRTF v = new Default(null); v.Layouts.Add(new ElementLayout(null, ElementFormat.UShort4N, 0, ElementUsage.Position, 0)); v.Layouts.Add(new ElementLayout(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]; VRTF.ElementLayout position = vrtf.Layouts .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.Position); VRTF.ElementLayout normal = vrtf.Layouts .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.Normal); VRTF.ElementLayout[] uv = vrtf.Layouts .Where(x => x.Usage == VRTF.ElementUsage.UV) .ToArray(); VRTF.ElementLayout blendIndices = vrtf.Layouts .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.BlendIndex); VRTF.ElementLayout blendWeights = vrtf.Layouts .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.BlendWeight); VRTF.ElementLayout tangents = vrtf.Layouts .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.Tangent); VRTF.ElementLayout color = vrtf.Layouts .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.Colour); if (uvscales == null) { uvscales = defaultUVScales; } foreach (Vertex 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++) { float 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); }
public VRTF(EventHandler handler, VRTF basis) : this(handler, basis.Version, basis.Stride, basis.Layouts, basis.ExtendedFormat) { }
public bool SetVertices(MLOD mlod, MLOD.Mesh mesh, int geoIndex, VRTF vrtf, Vertex[] vertices, float[] uvscales) { return(SetVertices(mlod, mesh, mesh.GeometryStates[geoIndex], vrtf, vertices, uvscales)); }
private bool SetVertices(MLOD mlod, GenericRCOLResource.GenericRCOLResource.ChunkReference myVBI, long beforeLength, int count, VRTF vrtf, IEnumerable <Vertex> vertices, float[] uvscales) { bool okay = true; byte[] before = new byte[beforeLength]; Array.Copy(mBuffer, before, before.Length); long afterPos = Math.Min(mBuffer.Length, beforeLength + (count * vrtf.Stride)); byte[] after = new byte[mBuffer.Length - afterPos]; Array.Copy(mBuffer, afterPos, after, 0, after.Length); long offset = 0; using (MemoryStream mg = new MemoryStream()) { if (!SetVertices(mg, vrtf, vertices, uvscales)) { okay = false; } offset = beforeLength + mg.Length - afterPos; mBuffer = new byte[before.Length + mg.Length + after.Length]; Array.Copy(before, mBuffer, before.Length); Array.Copy(mg.ToArray(), 0, mBuffer, before.Length, mg.Length); Array.Copy(after, 0, mBuffer, before.Length + mg.Length, after.Length); mg.Close(); } int voffset = (int)offset / vrtf.Stride; if (offset != 0) { foreach (MLOD.Mesh m in mlod.Meshes.Where(m => m.VertexBufferIndex.Equals(myVBI) && m.StreamOffset > beforeLength)) { m.StreamOffset = (uint)(m.StreamOffset + offset); foreach (MLOD.GeometryState g in m.GeometryStates) { if (g.MinVertexIndex * vrtf.Stride > beforeLength) { g.MinVertexIndex += voffset; } } } } return(okay); }
public bool SetVertices(MLOD mlod, int meshIndex, VRTF vrtf, Vertex[] vertices, float[] uvscales) { return(SetVertices(mlod, mlod.Meshes[meshIndex], vrtf, vertices, uvscales)); }
//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); VRTF.ElementLayout position = vrtf.Layouts .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.Position); VRTF.ElementLayout normal = vrtf.Layouts .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.Normal); VRTF.ElementLayout[] uv = vrtf.Layouts .Where(x => x.Usage == VRTF.ElementUsage.UV) .ToArray(); VRTF.ElementLayout blendIndices = vrtf.Layouts .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.BlendIndex); VRTF.ElementLayout blendWeights = vrtf.Layouts .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.BlendWeight); VRTF.ElementLayout tangents = vrtf.Layouts .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.Tangent); VRTF.ElementLayout 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++) { VRTF.ElementLayout u = uv[j]; float[] uvPoints = new float[VRTF.FloatCountFromFormat(u.Format)]; float 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); }
public Vertex[] GetVertices(MLOD.Mesh mesh, VRTF vrtf, MLOD.GeometryState geo, float[] uvscales) { return(GetVertices(vrtf, mesh.StreamOffset + (geo.MinVertexIndex * vrtf.Stride), geo.VertexCount, uvscales)); }
public Vertex[] GetVertices(MLOD.Mesh mesh, VRTF vrtf, float[] uvscales) { return(GetVertices(vrtf, mesh.StreamOffset, mesh.VertexCount, uvscales)); }