Ejemplo n.º 1
0
 public VertexBufferBuilder(int positionsCount, VertexDefinition vd)
 {
     _vd               = vd;
     _taken            = new bool[positionsCount];
     _vertices         = new List <VertexCache> [positionsCount];
     _vertexBufferData = new MemoryStream(positionsCount * vd.Size);
 }
Ejemplo n.º 2
0
        public void CreateVertexBuffer <T>(Span <T> data) where T : unmanaged
        {
            _vd = VertexDefinition.GetDefinition <T>();
            _vb = new VertexBuffer(_vd);

            _vb.SetData(data);
        }
Ejemplo n.º 3
0
Archivo: Font.cs Proyecto: ndech/Alpha
        public Vector2I UpdateVertexArray(string text, ref VertexDefinition.PositionTextureColor[] vertices, ref Buffer vertexBuffer, Color defaultColor, List<TexturedRectangle> icons, int positionX = 0, int positionY = 0)
        {
            icons.Clear();
            Color color = defaultColor;
            int width = 0;
            int maxWidth = 0;
            int height = Characters.First().Value.height;
            int maxHeight = height;
            for (int i = 0; i < text.Length; i++)
            {
                char letter = text[i];
                if (letter == '\n')
                {
                    maxWidth = Math.Max(maxWidth, width);
                    width = 0;
                    positionX = 0;
                    positionY += height;
                    maxHeight += height;
                    continue;
                }
                if (letter == '[')
                {
                    if (text[i + 1] == '[')
                        continue;
                    string token = text.Substring(i + 1, text.IndexOf(']', i + 1) - (i + 1));
                    if (!ColorParser.TryParse(token, out color))
                    {
                        if (token == "-")
                            color = defaultColor;
                        else if (token == "gold")
                        {
                            icons.Add(new TexturedRectangle(_context,
                                _context.TextureManager.Create("gold.png", "Data/UI/Icons/"), new Vector2I(height, height)));
                            positionX += height + 1;
                            width += height + 1;
                        }
                        else
                            throw new InvalidOperationException("Unexpected token : " + token);
                    }
                    i = text.IndexOf(']', i + 1);
                    continue;
                }
                Character c = Characters[letter];
                Vector4 colorAsVector = color.ToVector4();
                vertices[i * 4] = new VertexDefinition.PositionTextureColor { position = new Vector3(positionX, positionY, 0.0f), texture = new Vector2(c.uLeft, c.vTop), color = colorAsVector }; //Top left
                vertices[i * 4 + 1] = new VertexDefinition.PositionTextureColor { position = new Vector3(positionX + c.width, positionY + c.height, 0.0f), texture = new Vector2(c.uRight, c.vBottom), color = colorAsVector }; //Right bottom
                vertices[i * 4 + 2] = new VertexDefinition.PositionTextureColor { position = new Vector3(positionX, positionY + c.height, 0.0f), texture = new Vector2(c.uLeft, c.vBottom), color = colorAsVector }; //Left bottom
                vertices[i * 4 + 3] = new VertexDefinition.PositionTextureColor { position = new Vector3(positionX + c.width, positionY, 0.0f), texture = new Vector2(c.uRight, c.vTop), color = colorAsVector }; //Top right

                positionX += c.width + 1;
                width += c.width + 1;
            }
            DataStream mappedResource;
            _context.DirectX.Device.ImmediateContext.MapSubresource(vertexBuffer, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None,
                out mappedResource);
            mappedResource.WriteRange(vertices);
            _context.DirectX.Device.ImmediateContext.UnmapSubresource(vertexBuffer, 0);
            return  new Vector2I(Math.Max(maxWidth, width), maxHeight);
        }
Ejemplo n.º 4
0
 protected override void DefineLocation(VertexDefinition definition, Renderable target, Type vertexType)
 {
     definition.Map(vertexType, "vPos", VertexSpecialField.Position);
     definition.Map(vertexType, "vNormal", VertexSpecialField.Normal);
     definition.Map(vertexType, "vUV", VertexSpecialField.UV);
     definition.Map(vertexType, "bone", VertexSpecialField.Bone);
     definition.Map(vertexType, "weight", VertexSpecialField.Weight);
     definition.Map(vertexType, "vtexIndex", VertexSpecialField.TextureIndex);
 }
Ejemplo n.º 5
0
        protected virtual VertexDefinition ReadVertexDefinition()
        {
            var vertexDefinition = new VertexDefinition();

            vertexDefinition.Variable     = (VertexDefinition.VariableEnum)fileData[iPos];
            vertexDefinition.VariableType = (VertexDefinition.VariableTypeEnum)fileData[iPos + 1];
            vertexDefinition.Offset       = (int)fileData[iPos + 2];
            ColoredConsole.WriteLine("{0:x8}             {1} {2}", (object)iPos, (object)vertexDefinition.VariableType.ToString(), (object)vertexDefinition.Variable.ToString());
            iPos += 3;
            return(vertexDefinition);
        }
Ejemplo n.º 6
0
        public void OnDrawGizmos()
        {
            if (MeshFilter.mesh == null)
            {
                MeshFilter.mesh = new Mesh();
            }

            if (Points == null || Points.Count < 3)
            {
                return;
            }

            VertList = new List <VertexDefinition>();

            float colorNum = 0f;

            var lastVert = new VertexDefinition(Points.First().position, ColorUtility.HsvtoRgb(0, .8f, 1f));

            foreach (var point in Points)
            {
                var thisVert = new VertexDefinition(point.position,
                                                    ColorUtility.HsvtoRgb(colorNum, .8f, 1f),
                                                    lastVert.Position,
                                                    point.position);

                colorNum += COLOR_MOD;
                VertList.Add(thisVert);
                lastVert.NextPosition = thisVert.Position;
                lastVert = thisVert;
            }

            // last point required here to complete triangle

            MeshFilter.mesh.Clear();

            MeshFilter.mesh.vertices = VertList.Select(vertex => vertex.Position).ToArray();
            MeshFilter.mesh.colors   = VertList.Select(vertex => vertex.Color).ToArray();
            MeshFilter.mesh.normals  = VertList.Select(vertex => vertex.NextPosition - vertex.Position).ToArray();
            MeshFilter.mesh.tangents = VertList.Select(vertex => (vertex.LastPosition - vertex.Position).ConvertToVector4()).ToArray();


            var indices = new List <int>();

            for (var i = 0; i < VertList.Count; i++)
            {
                indices.Add(i);
            }

            MeshFilter.mesh.SetIndices(indices.ToArray(), MeshTopology.LineStrip, 0);

            MeshFilter.mesh.UploadMeshData(false);
        }
Ejemplo n.º 7
0
 public override Mesh CreateMesh()
 {
     return(new Mesh(VertexDefinition.GetDefinition <SkinnedVertex>()));
 }
Ejemplo n.º 8
0
        protected virtual VertexList ReadVertexList(int numberofvertices)
        {
            var vertexList = new VertexList();

            if (fileData[iPos] != (byte)0)
            {
                var vertexDefinition = new VertexDefinition();
                vertexDefinition.Variable     = VertexDefinition.VariableEnum.position;
                vertexDefinition.VariableType = (VertexDefinition.VariableTypeEnum)fileData[iPos];
                vertexList.VertexDefinitions.Add(vertexDefinition);
                ColoredConsole.WriteLine("{0:x8}             {1} {2}", (object)iPos, (object)vertexDefinition.VariableType.ToString(), (object)vertexDefinition.Variable.ToString());
            }
            iPos += 2;
            if (fileData[iPos] != (byte)0)
            {
                var vertexDefinition = new VertexDefinition();
                vertexDefinition.Variable     = VertexDefinition.VariableEnum.normal;
                vertexDefinition.VariableType = (VertexDefinition.VariableTypeEnum)fileData[iPos];
                vertexList.VertexDefinitions.Add(vertexDefinition);
                ColoredConsole.WriteLine("{0:x8}             {1} {2}", (object)iPos, (object)vertexDefinition.VariableType.ToString(), (object)vertexDefinition.Variable.ToString());
            }
            iPos += 2;
            if (fileData[iPos] != (byte)0)
            {
                var vertexDefinition = new VertexDefinition();
                vertexDefinition.Variable     = VertexDefinition.VariableEnum.colorSet0;
                vertexDefinition.VariableType = (VertexDefinition.VariableTypeEnum)fileData[iPos];
                vertexList.VertexDefinitions.Add(vertexDefinition);
                ColoredConsole.WriteLine("{0:x8}             {1} {2}", (object)iPos, (object)vertexDefinition.VariableType.ToString(), (object)vertexDefinition.Variable.ToString());
            }
            iPos += 2;
            if (fileData[iPos] != (byte)0)
            {
                var vertexDefinition = new VertexDefinition();
                vertexDefinition.Variable     = VertexDefinition.VariableEnum.tangent;
                vertexDefinition.VariableType = (VertexDefinition.VariableTypeEnum)fileData[iPos];
                vertexList.VertexDefinitions.Add(vertexDefinition);
                ColoredConsole.WriteLine("{0:x8}             {1} {2}", (object)iPos, (object)vertexDefinition.VariableType.ToString(), (object)vertexDefinition.Variable.ToString());
            }
            iPos += 2;
            if (fileData[iPos] != (byte)0)
            {
                var vertexDefinition = new VertexDefinition();
                vertexDefinition.Variable     = VertexDefinition.VariableEnum.colorSet1;
                vertexDefinition.VariableType = (VertexDefinition.VariableTypeEnum)fileData[iPos];
                vertexList.VertexDefinitions.Add(vertexDefinition);
                ColoredConsole.WriteLine("{0:x8}             {1} {2}", (object)iPos, (object)vertexDefinition.VariableType.ToString(), (object)vertexDefinition.Variable.ToString());
            }
            iPos += 2;
            if (fileData[iPos] != (byte)0)
            {
                var vertexDefinition = new VertexDefinition();
                vertexDefinition.Variable     = VertexDefinition.VariableEnum.uvSet01;
                vertexDefinition.VariableType = (VertexDefinition.VariableTypeEnum)fileData[iPos];
                vertexList.VertexDefinitions.Add(vertexDefinition);
                ColoredConsole.WriteLine("{0:x8}             {1} {2}", (object)iPos, (object)vertexDefinition.VariableType.ToString(), (object)vertexDefinition.Variable.ToString());
            }
            iPos += 2;
            iPos += 2;
            if (fileData[iPos] != (byte)0)
            {
                var vertexDefinition = new VertexDefinition();
                vertexDefinition.Variable     = VertexDefinition.VariableEnum.uvSet2;
                vertexDefinition.VariableType = (VertexDefinition.VariableTypeEnum)fileData[iPos];
                vertexList.VertexDefinitions.Add(vertexDefinition);
                ColoredConsole.WriteLine("{0:x8}             {1} {2}", (object)iPos, (object)vertexDefinition.VariableType.ToString(), (object)vertexDefinition.Variable.ToString());
            }
            iPos += 2;
            iPos += 2;
            if (fileData[iPos] != (byte)0)
            {
                var vertexDefinition = new VertexDefinition();
                vertexDefinition.Variable     = VertexDefinition.VariableEnum.blendIndices0;
                vertexDefinition.VariableType = (VertexDefinition.VariableTypeEnum)fileData[iPos];
                vertexList.VertexDefinitions.Add(vertexDefinition);
                ColoredConsole.WriteLine("{0:x8}             {1} {2}", (object)iPos, (object)vertexDefinition.VariableType.ToString(), (object)vertexDefinition.Variable.ToString());
            }
            iPos += 2;
            if (fileData[iPos] != (byte)0)
            {
                var vertexDefinition = new VertexDefinition();
                vertexDefinition.Variable     = VertexDefinition.VariableEnum.blendWeight0;
                vertexDefinition.VariableType = (VertexDefinition.VariableTypeEnum)fileData[iPos];
                vertexList.VertexDefinitions.Add(vertexDefinition);
                ColoredConsole.WriteLine("{0:x8}             {1} {2}", (object)iPos, (object)vertexDefinition.VariableType.ToString(), (object)vertexDefinition.Variable.ToString());
            }
            iPos += 2;
            if (fileData[iPos] != (byte)0)
            {
                var vertexDefinition = new VertexDefinition();
                vertexDefinition.Variable     = VertexDefinition.VariableEnum.lightDirSet;
                vertexDefinition.VariableType = (VertexDefinition.VariableTypeEnum)fileData[iPos];
                vertexList.VertexDefinitions.Add(vertexDefinition);
                ColoredConsole.WriteLine("{0:x8}             {1} {2}", (object)iPos, (object)vertexDefinition.VariableType.ToString(), (object)vertexDefinition.Variable.ToString());
            }
            iPos += 2;
            if (fileData[iPos] != (byte)0)
            {
                var vertexDefinition = new VertexDefinition();
                vertexDefinition.Variable     = VertexDefinition.VariableEnum.lightColSet;
                vertexDefinition.VariableType = (VertexDefinition.VariableTypeEnum)fileData[iPos];
                vertexList.VertexDefinitions.Add(vertexDefinition);
                ColoredConsole.WriteLine("{0:x8}             {1} {2}", (object)iPos, (object)vertexDefinition.VariableType.ToString(), (object)vertexDefinition.Variable.ToString());
            }
            iPos += 2;
            iPos += 6;
            ColoredConsole.WriteLine("{0:x8}           Number of Vertices: {1:x8}", (object)iPos, (object)numberofvertices);
            for (var index = 0; index < numberofvertices; ++index)
            {
                vertexList.Vertices.Add(ReadVertex(vertexList.VertexDefinitions));
            }
            return(vertexList);
        }
 void IDefinition.FromArray(byte[] buffer)
 {
     BinaryReader bin = new BinaryReader(new MemoryStream(buffer));
     VertexType = (VertexDefinition)bin.ReadInt32();
     VertexCount = bin.ReadUInt16();
     TriangleCount = bin.ReadUInt16();
     bin.BaseStream.Seek(16, SeekOrigin.Current);
     Compression = (CompressionFlags)bin.ReadUInt16();
     bin.BaseStream.Seek(28, SeekOrigin.Current);
     RawOffset = bin.ReadUInt32();
     RawSize = bin.ReadUInt32();
     HeaderSize = bin.ReadUInt32();
     RawDataSize = bin.ReadUInt32();
 }
Ejemplo n.º 10
0
 public VertexBuffer(VertexDefinition vd, byte[] data)
     : base(data)
 {
     _vd          = vd;
     _vertexCount = data.Length / vd.Size;
 }
Ejemplo n.º 11
0
 public VertexBuffer(VertexDefinition vd)
 {
     _vd = vd;
 }
Ejemplo n.º 12
0
 protected override void DefineLocation(VertexDefinition definition, Renderable target, Type vertexType)
 {
     definition.Map(vertexType, "_pos", VertexSpecialField.Position);
 }
Ejemplo n.º 13
0
 private void UpdateOverlayVertexBuffer(DeviceContext deviceContext, Resource overlayVertexBuffer, VertexDefinition.PositionColor[] vertices, int vertexCount)
 {
     var dataBox = deviceContext.MapSubresource(overlayVertexBuffer, 0, MapMode.WriteDiscard, MapFlags.None);
     Utilities.Write(dataBox.DataPointer, vertices, 0, vertexCount);
     deviceContext.UnmapSubresource(overlayVertexBuffer, 0);
 }
Ejemplo n.º 14
0
        public void Render()
        {
            var variantName = Object.DefaultModelVariant != StringId.Invalid ?
                              CacheContext.GetString(Object.DefaultModelVariant) :
                              "default";

            var modelVariant = Model.Variants.FirstOrDefault(v => (CacheContext.GetString(v.Name) ?? v.Name.ToString()) == variantName);

            if (modelVariant == null && Model.Variants.Count > 0)
            {
                modelVariant = Model.Variants.First();
            }

            UpdateTransform();
            Device.Transform.World = World;

            foreach (var region in modelVariant.Regions)
            {
                if (region.RenderModelRegionIndex >= RenderModel.Regions.Count)
                {
                    continue;
                }

                var renderModelRegion = RenderModel.Regions[region.RenderModelRegionIndex];

                if (region.Permutations.Count == 0)
                {
                    continue;
                }

                var permutation = region.Permutations[0];

                if (permutation.RenderModelPermutationIndex < 0 || permutation.RenderModelPermutationIndex >= renderModelRegion.Permutations.Count)
                {
                    continue;
                }

                var renderModelPermutation = renderModelRegion.Permutations[permutation.RenderModelPermutationIndex];

                var meshIndex       = renderModelPermutation.MeshIndex;
                var meshCount       = renderModelPermutation.MeshCount;
                var regionName      = CacheContext.GetString(region.Name) ?? region.Name.ToString();
                var permutationName = CacheContext.GetString(permutation.Name) ?? permutation.Name.ToString();

                for (var currentMeshIndex = 0; currentMeshIndex < meshCount; currentMeshIndex++)
                {
                    var mesh = RenderModel.Geometry.Meshes[meshIndex + currentMeshIndex];

                    var renderVertex  = VertexDefinition.Get(mesh.Type);
                    var streamTypes   = renderVertex.GetStreamTypes();
                    var streamIndex   = streamTypes.First().Key;
                    var primitiveType = D3DPrimitiveType.TriangleList;

                    switch (mesh.IndexBufferType)
                    {
                    case TagPrimitiveType.PointList:
                        primitiveType = D3DPrimitiveType.PointList;
                        break;

                    case TagPrimitiveType.LineList:
                        primitiveType = D3DPrimitiveType.LineList;
                        break;

                    case TagPrimitiveType.LineStrip:
                        primitiveType = D3DPrimitiveType.LineStrip;
                        break;

                    case TagPrimitiveType.TriangleList:
                        primitiveType = D3DPrimitiveType.TriangleList;
                        break;

                    case TagPrimitiveType.TriangleFan:
                        primitiveType = D3DPrimitiveType.TriangleFan;
                        break;

                    case TagPrimitiveType.TriangleStrip:
                        primitiveType = D3DPrimitiveType.TriangleStrip;
                        break;
                    }

                    Device.VertexDeclaration = renderVertex.GetDeclaration(Device);
                    Device.SetStreamSource(streamTypes.First().Key, VertexBuffers[mesh.VertexBufferIndices[streamIndex]], 0);
                    Device.Indices = IndexBuffers[mesh.IndexBufferIndices.Where(index => index != ushort.MaxValue).First()];

                    foreach (var part in mesh.Parts)
                    {
                        if (part.MaterialIndex != -1)
                        {
                            var material = Materials[part.MaterialIndex];

                            Device.RenderState.AlphaBlendEnable = (part.TypeNew == TagTool.Geometry.Mesh.Part.PartTypeNew.Transparent);

                            foreach (var entry in material.Textures)
                            {
                                var name = entry.Key;

                                if (name.StartsWith("diffuse_map") || name.StartsWith("base_map") || name == "foam_texture")
                                {
                                    Device.SetTexture(0, entry.Value.Texture);
                                    break;
                                }
                            }

                            Device.TextureState[0].ColorOperation = TextureOperation.Modulate;
                            Device.TextureState[0].ColorArgument1 = TextureArgument.TextureColor;
                            Device.TextureState[0].ColorArgument2 = TextureArgument.Current;
                            Device.RenderState.FillMode           = FillMode.Solid;
                        }

                        for (var currentSubPartIndex = 0; currentSubPartIndex < part.SubPartCount; currentSubPartIndex++)
                        {
                            var subPart = mesh.SubParts[part.FirstSubPartIndex + currentSubPartIndex];

                            Device.DrawIndexedPrimitives(primitiveType, 0, 0, subPart.VertexCount, subPart.FirstIndex, subPart.IndexCount - (primitiveType == D3DPrimitiveType.TriangleStrip ? 2 : 0));
                        }
                    }
                }
            }
        }
Ejemplo n.º 15
0
 public virtual Mesh CreateMesh()
 {
     return(new Mesh(VertexDefinition.GetDefinition <MeshVertex>()));
 }
Ejemplo n.º 16
0
 protected override void DefineLocation(VertexDefinition definition, Control target, Type vertexType)
 {
     definition.Map(vertexType, "_vPos", VertexSpecialField.Position);
     definition.Map(vertexType, "_vUV", VertexSpecialField.UV);
 }
Ejemplo n.º 17
0
 public Mesh(VertexDefinition vd)
 {
     _vd = vd;
     _vb = new VertexBuffer(vd);
 }
Ejemplo n.º 18
0
        public RenderObject(D3DDevice device, HaloOnlineCacheContext cacheContext, GameObject definition, RealPoint3d position, RealEulerAngles3d rotation)
        {
            if (device == null)
            {
                throw new ArgumentNullException(nameof(device));
            }
            else if (cacheContext == null)
            {
                throw new ArgumentNullException(nameof(cacheContext));
            }
            else if (definition == null)
            {
                throw new ArgumentNullException(nameof(definition));
            }

            Device       = device;
            CacheContext = cacheContext;
            Object       = definition;

            Position = position;
            Rotation = rotation;
            UpdateTransform();

            using (var cacheStream = CacheContext.OpenTagCacheRead())
            {
                if (Object.Model == null)
                {
                    throw new NullReferenceException(nameof(Object.Model));
                }

                Model = CacheContext.Deserialize <Model>(new TagSerializationContext(cacheStream, CacheContext, Object.Model));

                if (Model.RenderModel == null)
                {
                    throw new NullReferenceException(nameof(Model.RenderModel));
                }

                RenderModel = CacheContext.Deserialize <RenderModel>(new TagSerializationContext(cacheStream, CacheContext, Model.RenderModel));

                if (Model.Variants == null || Model.Variants.Count == 0)
                {
                    var modelVariant = new Model.Variant
                    {
                        Name    = CacheContext.GetStringId("default"),
                        Regions = new List <Model.Variant.Region>()
                    };

                    foreach (var region in RenderModel.Regions)
                    {
                        var modelRegion = new Model.Variant.Region
                        {
                            Name = region.Name,
                            RenderModelRegionIndex = (sbyte)RenderModel.Regions.IndexOf(region),
                            Permutations           = new List <Model.Variant.Region.Permutation>()
                        };

                        foreach (var permutation in region.Permutations)
                        {
                            modelRegion.Permutations.Add(new Model.Variant.Region.Permutation
                            {
                                Name = modelVariant.Name,
                                RenderModelPermutationIndex = (sbyte)region.Permutations.IndexOf(permutation)
                            });
                        }

                        modelVariant.Regions.Add(modelRegion);
                    }

                    Model.Variants = new List <Model.Variant> {
                        modelVariant
                    };
                }

                Materials = new List <RenderMaterial>();

                foreach (var material in RenderModel.Materials)
                {
                    Materials.Add(new RenderMaterial(device, CacheContext, material));
                }

                if (RenderModel.Geometry.Resource == null)
                {
                    throw new NullReferenceException(nameof(RenderModel.Geometry.Resource));
                }

                RenderGeometryResource = CacheContext.Deserialize <RenderGeometryApiResourceDefinition>(RenderModel.Geometry.Resource);

                using (var resourceStream = new MemoryStream())
                    using (var reader = new BinaryReader(resourceStream))
                    {
                        CacheContext.ExtractResource(RenderModel.Geometry.Resource, resourceStream);

                        VertexBuffers = new Dictionary <int, VertexBuffer>();
                        IndexBuffers  = new Dictionary <int, IndexBuffer>();

                        var compression = RenderModel.Geometry.Compression[0];

                        foreach (var mesh in RenderModel.Geometry.Meshes)
                        {
                            var renderVertex = VertexDefinition.Get(mesh.Type);
                            var streamTypes  = renderVertex.GetStreamTypes();

                            foreach (var streamEntry in streamTypes)
                            {
                                var vertexBufferIndex = mesh.VertexBufferIndices[streamEntry.Key];

                                if (vertexBufferIndex == ushort.MaxValue || VertexBuffers.ContainsKey(vertexBufferIndex))
                                {
                                    continue;
                                }

                                var vbDef = RenderGeometryResource.VertexBuffers[vertexBufferIndex].Definition;

                                var vb     = new VertexBuffer(streamEntry.Value, vbDef.Data.Size, device, Usage.DoNotClip, renderVertex.GetStreamFormat(streamEntry.Key), Pool.Managed);
                                var vbData = vb.Lock(0, vbDef.Data.Size, LockFlags.None);

                                resourceStream.Position = vbDef.Data.Address.Offset;

                                var vertices = Array.CreateInstance(streamEntry.Value, vbDef.Count);

                                for (var i = 0; i < vbDef.Count; i++)
                                {
                                    var handle = GCHandle.Alloc(reader.ReadBytes(Marshal.SizeOf(streamEntry.Value)), GCHandleType.Pinned);
                                    var vertex = Marshal.PtrToStructure(handle.AddrOfPinnedObject(), streamEntry.Value);

                                    var positionField = streamEntry.Value.GetField("Position");

                                    if (positionField != null)
                                    {
                                        var xyz = (Vector3)positionField.GetValue(vertex);

                                        positionField.SetValue(vertex, new Vector3(
                                                                   xyz.X * compression.X.Length + compression.X.Lower,
                                                                   xyz.Y * compression.Y.Length + compression.Y.Lower,
                                                                   xyz.Z * compression.Z.Length + compression.Z.Lower));
                                    }

                                    var texcoordField = streamEntry.Value.GetField("Texcoord");

                                    if (texcoordField != null)
                                    {
                                        var uv = (Vector2)texcoordField.GetValue(vertex);

                                        texcoordField.SetValue(vertex, new Vector2(
                                                                   uv.X * compression.U.Length + compression.U.Lower,
                                                                   uv.Y * compression.V.Length + compression.V.Lower));
                                    }

                                    vertices.SetValue(vertex, i);

                                    handle.Free();
                                }

                                vbData.Write(vertices);
                                vb.Unlock();

                                VertexBuffers[vertexBufferIndex] = vb;
                            }

                            foreach (var indexBufferIndex in mesh.IndexBufferIndices)
                            {
                                if (indexBufferIndex == ushort.MaxValue || IndexBuffers.ContainsKey(indexBufferIndex))
                                {
                                    continue;
                                }

                                var ibDef = RenderGeometryResource.IndexBuffers[indexBufferIndex].Definition;

                                switch (ibDef.Format)
                                {
                                case IndexBufferFormat.PointList:
                                    mesh.IndexBufferType = TagPrimitiveType.PointList;
                                    break;

                                case IndexBufferFormat.LineList:
                                    mesh.IndexBufferType = TagPrimitiveType.LineList;
                                    break;

                                case IndexBufferFormat.LineStrip:
                                    mesh.IndexBufferType = TagPrimitiveType.LineStrip;
                                    break;

                                case IndexBufferFormat.TriangleList:
                                    mesh.IndexBufferType = TagPrimitiveType.TriangleList;
                                    break;

                                case IndexBufferFormat.TriangleFan:
                                    mesh.IndexBufferType = TagPrimitiveType.TriangleFan;
                                    break;

                                case IndexBufferFormat.TriangleStrip:
                                    mesh.IndexBufferType = TagPrimitiveType.TriangleStrip;
                                    break;
                                }

                                var ib     = new IndexBuffer(device, ibDef.Data.Size, Usage.DoNotClip, Pool.Managed, true);
                                var ibData = ib.Lock(0, ibDef.Data.Size, LockFlags.None);

                                resourceStream.Position = ibDef.Data.Address.Offset;

                                var indices = new ushort[ibDef.Data.Size / 2];

                                for (var i = 0; i < ibDef.Data.Size / 2; i++)
                                {
                                    indices[i] = reader.ReadUInt16();
                                }

                                ibData.Write(indices);
                                ib.Unlock();

                                IndexBuffers[indexBufferIndex] = ib;
                            }
                        }
                    }
            }
        }
        public void CreateSurface(NameValueMap nv)
        {
            var T0 = DateTime.Now;
            var T1 = DateTime.Now;
            var T2 = DateTime.Now;

            var N  = 100;
            var Nu = N;    // number of u control points
            var Lx = 10.0; // x-extent in cm
            var Nv = N;    // number of v control points
            var Ly = 10.0; // y-extent in cm

            var tg       = mApp.TransientGeometry;
            var partDoc  = (PartDocument)mApp.ActiveDocument;
            var cd       = partDoc.ComponentDefinition;
            var features = cd.Features;

            int dimU     = 3 + Nu;
            int dimV     = 3 + Nv;
            int dimC     = 3 * Nu * Nv;
            var uKnots   = new double[dimU];
            var vKnots   = new double[dimV];
            var controls = new double[dimC];
            // NOTE: The Inventor documentation does not seem to mention this,
            // but providing an empty array of weights apparently causes
            // Inventor to assume all points are equally weighted.
            //var weights = new double[Nu * Nv];
            var weights = new double[0];

            for (int i = 0; i <= 2; ++i)
            {
                uKnots[i] = vKnots[i] = 0.0;
            }

            for (int u = 3; u < Nu; ++u)
            {
                uKnots[u] = (u - 2) * (1.0f / (Nu - 2));
            }
            for (int v = 3; v < Nv; ++v)
            {
                vKnots[v] = (v - 2) * (1.0f / (Nv - 2));
            }

            for (int u = Nu; u < Nu + 3; ++u)
            {
                uKnots[u] = 1.0;
            }
            for (int v = Nv; v < Nv + 3; ++v)
            {
                vKnots[v] = 1.0;
            }

            for (int u = 0; u < Nu; ++u)
            {
                var x = u * Lx / (Nu - 1);
                for (int v = 0; v < Nv; ++v)
                {
                    var y = v * Ly / (Nv - 1);

                    var idx = 3 * (v * Nu + u);
                    controls[idx]     = x;
                    controls[idx + 1] = y;
                    var r = Math.Sqrt(x * x + y * y);
                    controls[idx + 2] = 0.3 * Math.Cos(2 * r);
                }
            }

            var polesu0 = new double[3 * Nv]; // u = 0 edge
            var polesuN = new double[3 * Nv]; // u = Nu-1 edge
            var polesv0 = new double[3 * Nu]; // v = 0 edge
            var polesvN = new double[3 * Nu]; // v = Nv-1 edge

            for (int u = 0; u < Nu; ++u)
            {
                // The v0 edge runs from (0, 0) to (Nu - 1, 0)
                int v0base = 3 * u;
                // The vN edge runs from (Nu - 1, Nv - 1) to (0, Nv - 1)
                int vNbase = 3 * ((Nu - 1 - u) + Nu * (Nv - 1));
                for (int k = 0; k < 3; ++k)
                {
                    polesv0[3 * u + k] = controls[v0base + k];
                    polesvN[3 * u + k] = controls[vNbase + k];
                }
            }
            for (int v = 0; v < Nv; ++v)
            {
                // The u0 edge runs from (0, Nv - 1) to (0, 0)
                int u0base = 3 * Nu * (Nv - 1 - v);
                // The uN edge runs from (Nu - 1, 0) to (Nu - 1, Nv - 1)
                int uNbase = 3 * (Nu - 1 + Nu * v);
                for (int k = 0; k < 3; ++k)
                {
                    polesu0[3 * v + k] = controls[u0base + k];
                    polesuN[3 * v + k] = controls[uNbase + k];
                }
            }

            var order = new int[2] {
                3, 3
            };
            var isPeriodic = new bool[2] {
                false, false
            };

            var transaction = mApp.TransactionManager.StartTransaction(mApp.ActiveDocument, "Create B-Spline Surface");

            try
            {
                var curvev0 = tg.CreateBSplineCurve(3, ref polesv0, ref uKnots, ref weights, isPeriodic[0]);
                var curveuN = tg.CreateBSplineCurve(3, ref polesuN, ref vKnots, ref weights, isPeriodic[1]);

                // TODO: Should the knots be reversed for curvevN and curve u0?
                // We can get away with not reversing them now because they are always symmetric.
                var curvevN = tg.CreateBSplineCurve(3, ref polesvN, ref uKnots, ref weights, isPeriodic[0]);
                var curveu0 = tg.CreateBSplineCurve(3, ref polesu0, ref vKnots, ref weights, isPeriodic[1]);

                var topSurface = tg.CreateBSplineSurface(ref order, ref controls, ref uKnots, ref vKnots, ref weights, ref isPeriodic);

                if (topSurface == null)
                {
                    throw new Exception("TransientGeometry.CreateBSplineSurface returned null");
                }

                var bodyDef = mApp.TransientBRep.CreateSurfaceBodyDefinition();

                var corners = new VertexDefinition[4];
                corners[0] = bodyDef.VertexDefinitions.Add(tg.CreatePoint(controls[0], controls[1], controls[2]));
                int c1 = 3 * (Nu - 1);
                corners[1] = bodyDef.VertexDefinitions.Add(tg.CreatePoint(controls[c1], controls[c1 + 1], controls[c1 + 2]));
                int c2 = c1 + 3 * Nu * (Nv - 1);
                corners[2] = bodyDef.VertexDefinitions.Add(tg.CreatePoint(controls[c2], controls[c2 + 1], controls[c2 + 2]));
                int c3 = 3 * Nu * (Nv - 1);
                corners[3] = bodyDef.VertexDefinitions.Add(tg.CreatePoint(controls[c3], controls[c3 + 1], controls[c3 + 2]));

                var edges = new EdgeDefinition[4];
                edges[0] = bodyDef.EdgeDefinitions.Add(corners[0], corners[1], curvev0);
                edges[1] = bodyDef.EdgeDefinitions.Add(corners[1], corners[2], curveuN);
                edges[2] = bodyDef.EdgeDefinitions.Add(corners[2], corners[3], curvevN);
                edges[3] = bodyDef.EdgeDefinitions.Add(corners[3], corners[0], curveu0);

                var lumpDef  = bodyDef.LumpDefinitions.Add();
                var shellDef = lumpDef.FaceShellDefinitions.Add();

                var topFace = shellDef.FaceDefinitions.Add(topSurface, false);
                // TODO: What is this ID for?
                topFace.AssociativeID = 501;

                var topFaceLoop = topFace.EdgeLoopDefinitions.Add();
                topFaceLoop.EdgeUseDefinitions.Add(edges[3], false);
                topFaceLoop.EdgeUseDefinitions.Add(edges[2], false);
                topFaceLoop.EdgeUseDefinitions.Add(edges[1], true);
                topFaceLoop.EdgeUseDefinitions.Add(edges[0], true);

                T1 = DateTime.Now;
                NameValueMap errors;
                var          newBody = bodyDef.CreateTransientSurfaceBody(out errors);
                T2 = DateTime.Now;

                if (newBody == null)
                {
                    throw new Exception("SurfaceBodyDefinition.CreateTransientSurfaceBody returned null");
                }

                NonParametricBaseFeatureDefinition baseDef = features.NonParametricBaseFeatures.CreateDefinition();
                ObjectCollection objColl = mApp.TransientObjects.CreateObjectCollection();
                objColl.Add(newBody);
                baseDef.BRepEntities = objColl;
                baseDef.OutputType   = BaseFeatureOutputTypeEnum.kSurfaceOutputType;
                NonParametricBaseFeature baseFeature = features.NonParametricBaseFeatures.AddByDefinition(baseDef);

                transaction.End();
            }
            catch (Exception exc)
            {
                transaction.Abort();
            }

            var Tfinal = DateTime.Now;

            var d01   = T1 - T0;
            var msg01 = string.Format("Time before CreateTransientSurfaceBody: {0} sec", d01.TotalSeconds);
            var d12   = T2 - T1;
            var msg12 = string.Format("CreateTransientSurfaceBody time: {0} sec", d12.TotalSeconds);
            var d2f   = Tfinal - T2;
            var msg2f = string.Format("Time after CreateTransientSurfaceBody: {0} sec", d2f.TotalSeconds);

            MessageBox.Show(msg01 + "\n" + msg12 + "\n" + msg2f);
        }