Пример #1
0
        private bool SetVertices(MLOD mlod, s4pi.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 (var m in mlod.Meshes.Where(m => m.VertexBufferIndex.Equals(myVBI) && m.StreamOffset > beforeLength))
                {
                    m.StreamOffset = (uint)(m.StreamOffset + offset);
                    foreach (var g in m.GeometryStates)
                    {
                        if (g.MinVertexIndex * vrtf.Stride > beforeLength)
                        {
                            g.MinVertexIndex += voffset;
                        }
                    }
                }
            }
            return(okay);
        }
Пример #2
0
 public bool SetVertices(MLOD mlod, int meshIndex, VRTF vrtf, Vertex[] vertices, float[] uvscales)
 {
     return(SetVertices(mlod, mlod.Meshes[meshIndex], vrtf, vertices, uvscales));
 }
Пример #3
0
 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));
 }
Пример #4
0
        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);
        }
Пример #5
0
        //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;
            }
        }
Пример #6
0
 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));
 }
Пример #7
0
 public Vertex[] GetVertices(MLOD.Mesh mesh, VRTF vrtf, float[] uvscales)
 {
     return(GetVertices(vrtf, mesh.StreamOffset, mesh.VertexCount, uvscales));
 }
Пример #8
0
        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);
        }
Пример #9
0
 public VRTF(int APIversion, EventHandler handler, VRTF basis) : this(APIversion, handler, basis.Version, basis.Stride, basis.Layouts, basis.ExtendedFormat)
 {
 }
Пример #10
0
        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);
        }