public TexturedMeshBinder(Autodesk.Dynamo.MeshToolkit.Mesh mesh, Color color, string textureFileName, Vector2Collection textureCoordinates)
        {
            StartingPositions = mesh.Vertices().ToTriples().ToArray();
            Color             = color;

            try { diffuseMap = new BitmapImage(new Uri(textureFileName)); }
            catch (FileNotFoundException) { throw new Exception("Could not locate the texture file"); }

            this.textureCoordinates = textureCoordinates;

            faceIndices = mesh.VertexIndicesByTri();
            int faceCount = faceIndices.Count / 3;

            faces = new IndexGroup[faceCount];

            for (int i = 0; i < faceCount; i++)
            {
                faces[i] = IndexGroup.ByIndices(
                    (uint)faceIndices[i * 3],
                    (uint)faceIndices[i * 3 + 1],
                    (uint)faceIndices[i * 3 + 2]);
            }

            meshFaceIndices = new IntCollection();

            foreach (IndexGroup face in faces)
            {
                meshFaceIndices.Add((int)face.A);
                meshFaceIndices.Add((int)face.B);
                meshFaceIndices.Add((int)face.C);
            }
        }
Exemple #2
0
        /// <summary>
        /// Create a Mesh, with found props
        /// </summary>
        /// <param name="positions"></param>
        /// <param name="textureCoordinates"></param>
        /// <param name="triangleIndices"></param>
        /// <param name="normals"></param>
        /// <param name="tangents"></param>
        /// <param name="bitangents"></param>
        /// <param name="material"></param>
        /// <param name="transforms"></param>
        private void CreateMesh(Vector3Collection positions, Vector2Collection textureCoordinates, IntCollection triangleIndices, List <Matrix> transforms,
                                out Vector3Collection normals, out Vector3Collection tangents, out Vector3Collection bitangents, MaterialCore material)
        {
            ComputeNormals(positions, triangleIndices, out normals);
            if (textureCoordinates == null)
            {
                textureCoordinates = new Vector2Collection();
                foreach (var pos in positions)
                {
                    textureCoordinates.Add(Vector2.One);
                }
            }
            MeshBuilder.ComputeTangents(positions, normals, textureCoordinates, triangleIndices, out tangents, out bitangents);
            MeshGeometry3D mesh = new MeshGeometry3D()
            {
                Positions          = positions,
                Normals            = normals,
                TextureCoordinates = textureCoordinates,
                Indices            = triangleIndices,
                Tangents           = tangents,
                BiTangents         = bitangents
            };
            Object3D ob3d = new Object3D();

            ob3d.Geometry  = mesh;
            ob3d.Material  = material;
            ob3d.Transform = transforms;
            ob3d.Name      = "Default";
            this.obGroup.Add(ob3d);
        }
 protected BillboardSingleImage3D()
 {
     Positions          = new Vector3Collection(6);
     Colors             = new Color4Collection(6);
     TextureCoordinates = new Vector2Collection(6);
     MaskColor          = Color.Transparent;
 }
        public BillboardText3D()
        {
            Positions = new Vector3Collection();
            Colors = new Color4Collection();
            TextureCoordinates = new Vector2Collection();

            this.TextInfo = new List<TextInfo>();

            var assembly = Assembly.GetExecutingAssembly();

            //Read the texture description
            using(var texDescriptionStream = assembly.GetManifestResourceStream("HelixToolkit.Wpf.SharpDX.Textures.arial.fnt"))
            {
                bmpFont = new BitmapFont();
                bmpFont.Load(texDescriptionStream);
            }

            //Read the texture
            using(var texImageStream = assembly.GetManifestResourceStream("HelixToolkit.Wpf.SharpDX.Textures.arial.png"))
            {
                var image = new BitmapImage();
                image.BeginInit();
                image.StreamSource = texImageStream;
                image.EndInit();

                Texture = image;
            }
        }
Exemple #5
0
        private static List <MeshGeometryModel3D> GenerateMeshGeometryModels(MGEOFile mgeo)
        {
            List <MeshGeometryModel3D> models = new List <MeshGeometryModel3D>(mgeo.Objects.Count);

            foreach (MGEOObject mgeoModel in mgeo.Objects)
            {
                IntCollection     indices  = new IntCollection(mgeoModel.Indices.Select(x => (int)x).AsEnumerable());
                Vector3Collection vertices = new Vector3Collection(mgeoModel.Vertices.Count);
                Vector2Collection uvs      = new Vector2Collection(mgeoModel.Vertices.Count);
                foreach (MGEOVertex vertex in mgeoModel.Vertices)
                {
                    vertices.Add(new dxVector3(vertex.Position.X, vertex.Position.Y, vertex.Position.Z));
                    uvs.Add(new dxVector2(vertex.DiffuseUV.X, vertex.DiffuseUV.Y));
                }

                MeshGeometry3D meshGeometry = new MeshGeometry3D()
                {
                    Indices            = indices,
                    Positions          = vertices,
                    TextureCoordinates = uvs
                };

                MeshGeometryModel3D model = new MeshGeometryModel3D()
                {
                    Geometry = meshGeometry,
                    Material = DiffuseMaterials.Pearl,
                    Name     = mgeoModel.Name
                };

                models.Add(model);
            }

            return(models);
        }
 public BillboardSingleText3D()
 {
     Positions = new Vector3Collection();
     Colors = new Color4Collection();
     TextureCoordinates = new Vector2Collection();
     TextInfo = new TextInfo();
 }
Exemple #7
0
 public MeshModel(Vector3Collection positions, Vector3Collection normals, IntCollection triangleIndices, Vector2Collection textureCoordinates)
 {
     Positions          = positions;
     Normals            = normals;
     TriangleIndices    = triangleIndices;
     TextureCoordinates = textureCoordinates;
 }
 public BillboardSingleText3D()
 {
     Positions          = new Vector3Collection();
     Colors             = new Color4Collection();
     TextureCoordinates = new Vector2Collection();
     TextInfo           = new TextInfo();
 }
        /// <summary>
        /// Creates a new mesh where no vertices are shared.
        /// </summary>
        /// <param name="input">
        /// The input mesh.
        /// </param>
        /// <returns>
        /// A new mesh.
        /// </returns>
        public static MeshGeometry3D NoSharedVertices(this MeshGeometry3D input)
        {
            var p  = new Point3DCollection();
            var ti = new Int32Collection();
            Vector3DCollection n = null;

            if (input.Normals != null)
            {
                n = new Vector3DCollection();
            }

            PointCollection tc = null;

            if (input.TextureCoordinates != null)
            {
                tc = new PointCollection();
            }

            for (var i = 0; i < input.TriangleIndices.Count; i += 3)
            {
                var i0     = i;
                var i1     = i + 1;
                var i2     = i + 2;
                var index0 = input.TriangleIndices[i0];
                var index1 = input.TriangleIndices[i1];
                var index2 = input.TriangleIndices[i2];
                var p0     = input.Positions[index0];
                var p1     = input.Positions[index1];
                var p2     = input.Positions[index2];
                p.Add(p0);
                p.Add(p1);
                p.Add(p2);
                ti.Add(i0);
                ti.Add(i1);
                ti.Add(i2);
                if (n != null && input.Normals.Count > 0)
                {
                    n.Add(input.Normals[index0]);
                    n.Add(input.Normals[index1]);
                    n.Add(input.Normals[index2]);
                }

                if (tc != null)
                {
                    tc.Add(input.TextureCoordinates[index0]);
                    tc.Add(input.TextureCoordinates[index1]);
                    tc.Add(input.TextureCoordinates[index2]);
                }
            }

#if SHARPDX
            return(new MeshGeometry3D {
                Positions = p, TriangleIndices = new IntCollection(ti), Normals = n, TextureCoordinates = tc
            });
#else
            return(new MeshGeometry3D {
                Positions = p, TriangleIndices = ti, Normals = n, TextureCoordinates = tc
            });
#endif
        }
Exemple #10
0
 public BillboardText3D()
 {
     Positions          = new Vector3Collection();
     Colors             = new Color4Collection();
     TextureCoordinates = new Vector2Collection();
     TextInfo           = new List <TextInfo>();
 }
        public BillboardText3D()
        {
            Positions          = new Vector3Collection();
            Colors             = new Color4Collection();
            TextureCoordinates = new Vector2Collection();

            this.TextInfo = new List <TextInfo>();

            var assembly = Assembly.GetExecutingAssembly();

            //Read the texture description
            using (var texDescriptionStream = assembly.GetManifestResourceStream("HelixToolkit.Wpf.SharpDX.Textures.arial.fnt"))
            {
                bmpFont = new BitmapFont();
                bmpFont.Load(texDescriptionStream);
            }

            //Read the texture
            using (var texImageStream = assembly.GetManifestResourceStream("HelixToolkit.Wpf.SharpDX.Textures.arial.png"))
            {
                var image = new BitmapImage();
                image.BeginInit();
                image.StreamSource = texImageStream;
                image.EndInit();

                Texture = image;
            }
        }
        public static MeshGeometry3D Merge(params MeshGeometry3D[] meshes)
        {
            var positions = new Vector3Collection();
            var indices   = new IntCollection();

            var normals      = meshes.All(x => x.Normals != null) ? new Vector3Collection() : null;
            var colors       = meshes.All(x => x.Colors != null) ? new Color4Collection() : null;
            var textureCoods = meshes.All(x => x.TextureCoordinates != null) ? new Vector2Collection() : null;
            var tangents     = meshes.All(x => x.Tangents != null) ? new Vector3Collection() : null;
            var bitangents   = meshes.All(x => x.BiTangents != null) ? new Vector3Collection() : null;

            int index = 0;

            foreach (var part in meshes)
            {
                positions.AddRange(part.Positions);
                indices.AddRange(part.Indices.Select(x => x + index));
                index += part.Positions.Count;
            }

            if (normals != null)
            {
                normals = new Vector3Collection(meshes.SelectMany(x => x.Normals));
            }

            if (colors != null)
            {
                colors = new Color4Collection(meshes.SelectMany(x => x.Colors));
            }

            if (textureCoods != null)
            {
                textureCoods = new Vector2Collection(meshes.SelectMany(x => x.TextureCoordinates));
            }

            if (tangents != null)
            {
                tangents = new Vector3Collection(meshes.SelectMany(x => x.Tangents));
            }

            if (bitangents != null)
            {
                bitangents = new Vector3Collection(meshes.SelectMany(x => x.BiTangents));
            }

            var mesh = new MeshGeometry3D()
            {
                Positions = positions,
                Indices   = indices,
            };

            mesh.Normals            = normals;
            mesh.Colors             = colors;
            mesh.TextureCoordinates = textureCoods;
            mesh.Tangents           = tangents;
            mesh.BiTangents         = bitangents;

            return(mesh);
        }
Exemple #13
0
 public static void AssertContains(this Vector2Collection collection, params double[][] points)
 {
     Assert.AreEqual(points.Length, collection.Count, "Expected to find {0} points in collection", points.Length);
     foreach (var point in points)
     {
         Assert.IsTrue(collection.Contains(point), "Expected collection to contain point [{0},{1}]", point[0], point[1]);
     }
 }
Exemple #14
0
        public static IEnumerable <double> ToEnumerable(this Vector2Collection collection)
        {
            foreach (var v in collection)
            {
                yield return(v.X);

                yield return(v.Y);
            }
        }
        public BillboardText3D()
        {
            Positions = new Vector3Collection();
            Colors = new Color4Collection();
            TextureCoordinates = new Vector2Collection();
            TextInfo = new List<TextInfo>();

            Initialize();
        }
Exemple #16
0
 public BillboardSingleText3D(float width, float height)
 {
     Positions          = new Vector3Collection(12);
     Colors             = new Color4Collection(12);
     TextureCoordinates = new Vector2Collection(12);
     TextInfo           = new TextInfo();
     Width          = width;
     Height         = height;
     predefinedSize = true;
 }
Exemple #17
0
        private Vector2Collection ReadTexCoords(BinaryReader reader)
        {
            int size = reader.ReadUInt16();
            var pts  = new Vector2Collection();

            for (int i = 0; i < size; i++)
            {
                float x = reader.ReadSingle();
                float y = reader.ReadSingle();
                pts.Add(new Vector2(x, 1 - y));
            }
            return(pts);
        }
        private void CreatePerlinNoise()
        {
            float[] noise;
            MathHelper.GenerateNoiseMap(Width, Height, 8, out noise);
            Vector2Collection collection = new Vector2Collection(Width * Height);

            for (int i = 0; i < Width; ++i)
            {
                for (int j = 0; j < Height; ++j)
                {
                    collection.Add(new Vector2(Math.Abs(noise[Width * i + j]), 0));
                }
            }
            Model.TextureCoordinates = collection;
        }
Exemple #19
0
        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            if (value == null)
            {
                throw GetConvertFromException(value);
            }

            var source = value as string;

            if (source != null)
            {
                return(Vector2Collection.Parse(source));
            }

            return(base.ConvertFrom(context, culture, value));
        }
Exemple #20
0
        public static MeshGeometry3D GetRect(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3)
        {
            var positions       = new Vector3Collection();
            var triangleIndices = new HelixToolkit.Wpf.SharpDX.Core.IntCollection();

            var normals = new Vector3Collection();
            //private Vector3Collection tangents;
            //private Vector3Collection bitangents;
            var textureCoordinates = new Vector2Collection();

            var widthOrientation  = new Vector3(0, 0, 1);
            var heightOrientation = new Vector3(0, 1, 0);

            positions.Add(p0);
            positions.Add(p1);
            positions.Add(p2);
            positions.Add(p3);

            normals.Add(new Vector3(1, 0, 0));
            normals.Add(new Vector3(1, 0, 0));
            normals.Add(new Vector3(1, 0, 0));
            normals.Add(new Vector3(1, 0, 0));


            textureCoordinates.Add(new Vector2(0, 0));
            textureCoordinates.Add(new Vector2(1, 0));
            textureCoordinates.Add(new Vector2(1, 1));
            textureCoordinates.Add(new Vector2(0, 1));

            triangleIndices.Add(2);
            triangleIndices.Add(1);
            triangleIndices.Add(0);

            triangleIndices.Add(0);
            triangleIndices.Add(3);
            triangleIndices.Add(2);

            return(new MeshGeometry3D()
            {
                Positions = positions,
                Indices = triangleIndices,
                Normals = normals,
                TextureCoordinates = textureCoordinates
            });
        }
Exemple #21
0
        public static IEnumerable <GroupNode> LoadMapMGEO(MGEOFile mgeo, MapData mapData, string mapPath)
        {
            foreach (MGEOObject mgeoModel in mgeo.Objects)
            {
                IntCollection     indices  = new IntCollection(mgeoModel.Indices.Select(x => (int)x).AsEnumerable());
                Vector3Collection vertices = new Vector3Collection(mgeoModel.Vertices.Count);
                Vector2Collection uvs      = new Vector2Collection(mgeoModel.Vertices.Count);
                foreach (MGEOVertex vertex in mgeoModel.Vertices)
                {
                    vertices.Add(new dxVector3(vertex.Position.X, vertex.Position.Y, vertex.Position.Z));
                    uvs.Add(new dxVector2(vertex.DiffuseUV.X, vertex.DiffuseUV.Y));
                }

                foreach (MGEOSubmesh submesh in mgeoModel.Submeshes)
                {
                    GroupNode groupNode = new GroupNode()
                    {
                        Name = mgeoModel.Name
                    };

                    MeshGeometry3D submeshGeometry3D = new MeshGeometry3D()
                    {
                        Indices            = indices.GetRange((int)submesh.StartIndex, (int)submesh.IndexCount) as IntCollection,
                        Positions          = vertices,
                        TextureCoordinates = uvs
                    };

                    DiffuseMaterial diffuseMaterial = new DiffuseMaterial()
                    {
                        Name        = submesh.Material,
                        DiffuseMap  = CreateMaterial(submesh.Material, mapData, mapPath),
                        EnableUnLit = true
                    };

                    groupNode.AddChildNode(new MeshNode()
                    {
                        Name     = mgeoModel.Name + "|" + submesh.Material,
                        Geometry = submeshGeometry3D,
                        Material = diffuseMaterial
                    });

                    yield return(groupNode);
                }
            }
        }
        public static Vector2Collection Parse(string source)
        {
            IFormatProvider formatProvider = CultureInfo.InvariantCulture;

            var th       = new TokenizerHelper(source, formatProvider);
            var resource = new Vector2Collection();

            Vector2 value;

            while (th.NextToken())
            {
                value = new Vector2(
                    Convert.ToSingle(th.GetCurrentToken(), formatProvider),
                    Convert.ToSingle(th.NextTokenRequired(), formatProvider));

                resource.Add(value);
            }

            return(resource);
        }
Exemple #23
0
        public static MeshGeometry3D GetRect(Vector3 center, float width, float height, Vector3 widthOrientation, Vector3 heightOrientation)
        {
            var positions       = new Vector3Collection();
            var triangleIndices = new HelixToolkit.Wpf.SharpDX.Core.IntCollection();

            var normals = new Vector3Collection();
            //private Vector3Collection tangents;
            //private Vector3Collection bitangents;
            var textureCoordinates = new Vector2Collection();

            positions.Add(center - widthOrientation * width / 2 - heightOrientation * height / 2);
            positions.Add(center + widthOrientation * width / 2 - heightOrientation * height / 2);
            positions.Add(center + widthOrientation * width / 2 + heightOrientation * height / 2);
            positions.Add(center - widthOrientation * width / 2 + heightOrientation * height / 2);

            normals.Add(new Vector3(1, 0, 0));
            normals.Add(new Vector3(1, 0, 0));
            normals.Add(new Vector3(1, 0, 0));
            normals.Add(new Vector3(1, 0, 0));

            textureCoordinates.Add(new Vector2(1, 1));
            textureCoordinates.Add(new Vector2(0, 1));
            textureCoordinates.Add(new Vector2(0, 0));
            textureCoordinates.Add(new Vector2(1, 0));

            triangleIndices.Add(2);
            triangleIndices.Add(1);
            triangleIndices.Add(0);

            triangleIndices.Add(0);
            triangleIndices.Add(3);
            triangleIndices.Add(2);

            return(new MeshGeometry3D()
            {
                Positions = positions,
                Indices = triangleIndices,
                Normals = normals,
                TextureCoordinates = textureCoordinates
            });
        }
        public BillboardText3D()
        {
            Positions          = new Vector3Collection();
            Colors             = new Color4Collection();
            TextureCoordinates = new Vector2Collection();

            this.TextInfo = new List <TextInfo>();

            var assembly = Assembly.GetExecutingAssembly();

            var texDescriptionFilePath = Path.GetTempFileName();
            var texImageFilePath       = Path.GetTempFileName();

            //Read the texture description
            var texDescriptionStream = assembly.GetManifestResourceStream("HelixToolkit.Wpf.SharpDX.Textures.arial.fnt");

            using (var fileStream = File.Create(texDescriptionFilePath))
            {
                texDescriptionStream.CopyTo(fileStream);
            }

            bmpFont = BitmapFontLoader.LoadFontFromFile(texDescriptionFilePath);

            //Read the texture
            var texImageStream = assembly.GetManifestResourceStream("HelixToolkit.Wpf.SharpDX.Textures.arial.png");

            using (var fileStream = File.Create(texImageFilePath))
            {
                texImageStream.CopyTo(fileStream);
            }

            Texture = new BitmapImage(new Uri(texImageFilePath));

            //Cleanup the temp files
            if (File.Exists(texDescriptionFilePath))
            {
                File.Delete(texDescriptionFilePath);
            }
        }
Exemple #25
0
        public static MeshGeometry3D GetCube(Vector3 minimum, Vector3 maximum)
        {
            var positions       = new Vector3Collection();
            var triangleIndices = new HelixToolkit.Wpf.SharpDX.Core.IntCollection();

            var normals            = new Vector3Collection();
            var textureCoordinates = new Vector2Collection();

            positions.Add(new Vector3(minimum.X, minimum.Y, minimum.Z)); //0
            positions.Add(new Vector3(maximum.X, minimum.Y, minimum.Z)); //1
            positions.Add(new Vector3(minimum.X, maximum.Y, minimum.Z)); //2
            positions.Add(new Vector3(minimum.X, minimum.Y, maximum.Z)); //3
            positions.Add(new Vector3(maximum.X, maximum.Y, minimum.Z)); //4
            positions.Add(new Vector3(maximum.X, minimum.Y, maximum.Z)); //5
            positions.Add(new Vector3(minimum.X, maximum.Y, maximum.Z)); //6
            positions.Add(new Vector3(maximum.X, maximum.Y, maximum.Z)); //7

            triangleIndices.AddRange(new[] { 0, 5, 3, 0, 1, 5 });
            triangleIndices.AddRange(new[] { 1, 7, 5, 1, 4, 7 });
            triangleIndices.AddRange(new[] { 4, 7, 2, 7, 6, 2 });
            triangleIndices.AddRange(new[] { 6, 3, 0, 6, 0, 2 });
            triangleIndices.AddRange(new[] { 6, 3, 5, 5, 7, 6 });
            triangleIndices.AddRange(new[] { 0, 1, 2, 2, 1, 4 });

            for (int i = 0; i < positions.Count; i++)
            {
                normals.Add(new Vector3(1, 0, 0));
                textureCoordinates.Add(new Vector2(0, 0));
            }


            return(new MeshGeometry3D()
            {
                Positions = positions,
                Indices = triangleIndices,
                Normals = normals,
                TextureCoordinates = textureCoordinates
            });
        }
        public BillboardText3D()
        {
            Positions = new Vector3Collection();
            Colors = new Color4Collection();
            TextureCoordinates = new Vector2Collection();

            this.TextInfo = new List<TextInfo>();

            var assembly = Assembly.GetExecutingAssembly();

            var texDescriptionFilePath = Path.GetTempFileName();
            var texImageFilePath = Path.GetTempFileName();

            //Read the texture description
            var texDescriptionStream = assembly.GetManifestResourceStream("HelixToolkit.Wpf.SharpDX.Textures.arial.fnt");
            using (var fileStream = File.Create(texDescriptionFilePath))
            {
                texDescriptionStream.CopyTo(fileStream);
            }

            bmpFont = BitmapFontLoader.LoadFontFromFile(texDescriptionFilePath);

            //Read the texture
            var texImageStream = assembly.GetManifestResourceStream("HelixToolkit.Wpf.SharpDX.Textures.arial.png");
            using (var fileStream = File.Create(texImageFilePath))
            {
                texImageStream.CopyTo(fileStream);
            }

            Texture = new BitmapImage(new Uri(texImageFilePath));

            //Cleanup the temp files
            if (File.Exists(texDescriptionFilePath))
            {
                File.Delete(texDescriptionFilePath);
            }
        }
Exemple #27
0
        protected void CalculateTextureCoordinates()
        {
            var uvCollection = new Vector2[Positions.Count];

            for (var i = 0; i < TriangleIndices.Count; i += 3)
            {
                var a     = Positions[TriangleIndices[i]];
                var b     = Positions[TriangleIndices[i + 1]];
                var c     = Positions[TriangleIndices[i + 2]];
                var side1 = b - a;
                var side2 = c - a;
                var n     = Vector3.Cross(side1, side2);
                n = new Vector3(Math.Abs(n.X), Math.Abs(n.Normalized().Y), Math.Abs(n.Normalized().Z));

                if (n.X > n.Y && n.X > n.Z)
                {
                    uvCollection[TriangleIndices[i]]     = new Vector2(Positions[TriangleIndices[i]].Z, Positions[TriangleIndices[i]].Y);
                    uvCollection[TriangleIndices[i + 1]] = new Vector2(Positions[TriangleIndices[i + 1]].Z, Positions[TriangleIndices[i + 1]].Y);
                    uvCollection[TriangleIndices[i + 2]] = new Vector2(Positions[TriangleIndices[i + 2]].Z, Positions[TriangleIndices[i + 2]].Y);
                }
                else if (n.Y > n.X && n.Y > n.Z)
                {
                    uvCollection[TriangleIndices[i]]     = new Vector2(Positions[TriangleIndices[i]].X, Positions[TriangleIndices[i]].Z);
                    uvCollection[TriangleIndices[i + 1]] = new Vector2(Positions[TriangleIndices[i + 1]].X, Positions[TriangleIndices[i + 1]].Z);
                    uvCollection[TriangleIndices[i + 2]] = new Vector2(Positions[TriangleIndices[i + 2]].X, Positions[TriangleIndices[i + 2]].Z);
                }
                else if (n.Z > n.X && n.Z > n.Y)
                {
                    uvCollection[TriangleIndices[i]]     = new Vector2(Positions[TriangleIndices[i]].X, Positions[TriangleIndices[i]].Y);
                    uvCollection[TriangleIndices[i + 1]] = new Vector2(Positions[TriangleIndices[i + 1]].X, Positions[TriangleIndices[i + 1]].Y);
                    uvCollection[TriangleIndices[i + 2]] = new Vector2(Positions[TriangleIndices[i + 2]].X, Positions[TriangleIndices[i + 2]].Y);
                }
            }

            TextureCoordinates = new Vector2Collection(uvCollection);
        }
Exemple #28
0
        /// <summary>
        /// Parses the MDL file to obtain model information
        /// </summary>
        /// <param name="selectedItem">The currently selected item</param>
        /// <param name="selectedRace">The currently selected race</param>
        /// <param name="selectedBody">The currently selected body</param>
        /// <param name="selectedPart">The currently selected part</param>
        /// <param name="selectedCategory">The items category </param>
        public MDL(ItemData selectedItem, string selectedCategory, string selectedRace, string selectedBody, string selectedPart)
        {
            string itemType  = Helper.GetCategoryType(selectedCategory);
            string MDLFolder = "";

            if (itemType.Equals("weapon") || itemType.Equals("food"))
            {
                if (selectedPart.Equals("Secondary"))
                {
                    MDLFolder = string.Format(Strings.WeapMDLFolder, selectedItem.SecondaryModelID, selectedItem.SecondaryModelBody);
                    MDLFile   = string.Format(Strings.WeapMDLFile, selectedItem.SecondaryModelID, selectedItem.SecondaryModelBody);
                }
                else
                {
                    MDLFolder = string.Format(Strings.WeapMDLFolder, selectedItem.PrimaryModelID, selectedItem.PrimaryModelBody);
                    MDLFile   = string.Format(Strings.WeapMDLFile, selectedItem.PrimaryModelID, selectedItem.PrimaryModelBody);
                }
            }
            else if (itemType.Equals("accessory"))
            {
                MDLFolder = string.Format(Strings.AccMDLFolder, selectedItem.PrimaryModelID);
                MDLFile   = string.Format(Strings.AccMDLFile, selectedRace, selectedItem.PrimaryModelID, Info.slotAbr[selectedCategory]);
            }
            else if (itemType.Equals("character"))
            {
                if (selectedItem.ItemName.Equals(Strings.Body))
                {
                    MDLFolder = string.Format(Strings.BodyMDLFolder, selectedRace, selectedBody.PadLeft(4, '0'));
                    MDLFile   = string.Format(Strings.BodyMDLFile, selectedRace, selectedBody.PadLeft(4, '0'), selectedPart);
                }
                else if (selectedItem.ItemName.Equals(Strings.Face))
                {
                    MDLFolder = string.Format(Strings.FaceMDLFolder, selectedRace, selectedBody.PadLeft(4, '0'));
                    MDLFile   = string.Format(Strings.FaceMDLFile, selectedRace, selectedBody.PadLeft(4, '0'), selectedPart);
                }
                else if (selectedItem.ItemName.Equals(Strings.Hair))
                {
                    MDLFolder = string.Format(Strings.HairMDLFolder, selectedRace, selectedBody.PadLeft(4, '0'));
                    MDLFile   = string.Format(Strings.HairMDLFile, selectedRace, selectedBody.PadLeft(4, '0'), selectedPart);
                }
                else if (selectedItem.ItemName.Equals(Strings.Tail))
                {
                    MDLFolder = string.Format(Strings.TailMDLFolder, selectedRace, selectedBody.PadLeft(4, '0'));
                    MDLFile   = string.Format(Strings.TailMDLFile, selectedRace, selectedBody.PadLeft(4, '0'), selectedPart);
                }
            }
            else if (itemType.Equals("monster"))
            {
                bool isDemiHuman = false;
                if (selectedItem.PrimaryMTRLFolder != null)
                {
                    isDemiHuman = selectedItem.PrimaryMTRLFolder.Contains("demihuman");
                }

                string ID   = "";
                string body = "";

                if (selectedCategory.Equals(Strings.Pets))
                {
                    int part = 1;

                    if (selectedItem.ItemName.Equals(Strings.Selene) || selectedItem.ItemName.Equals(Strings.Bishop_Autoturret))
                    {
                        part = 2;
                    }

                    ID   = Info.petID[selectedItem.ItemName];
                    body = part.ToString().PadLeft(4, '0');
                }
                else
                {
                    ID   = selectedItem.PrimaryModelID.PadLeft(4, '0');
                    body = selectedItem.PrimaryModelBody;
                }

                if (isDemiHuman)
                {
                    MDLFolder = string.Format(Strings.DemiMDLFolder, ID, body);
                    MDLFile   = string.Format(Strings.DemiMDLFile, ID, body, selectedPart);
                }
                else
                {
                    MDLFolder = string.Format(Strings.MonsterMDLFolder, ID, body);
                    MDLFile   = string.Format(Strings.MonsterMDLFile, ID, body);
                }
            }
            else
            {
                MDLFolder = string.Format(Strings.EquipMDLFolder, selectedItem.PrimaryModelID);

                if (selectedPart.Equals("-"))
                {
                    MDLFile = string.Format(Strings.EquipMDLFile, selectedRace, selectedItem.PrimaryModelID, Info.slotAbr[selectedCategory]);
                }
                else
                {
                    MDLFile = string.Format(Strings.EquipMDLFile, selectedRace, selectedItem.PrimaryModelID, selectedPart);
                }
            }

            fullPath = MDLFolder + "/" + MDLFile;
            int offset = Helper.GetDataOffset(FFCRC.GetHash(MDLFolder), FFCRC.GetHash(MDLFile), Strings.ItemsDat);

            if (offset == 0)
            {
                if (itemType.Equals("weapon"))
                {
                    if (selectedPart.Equals("Secondary"))
                    {
                        MDLFolder = string.Format(Strings.EquipMDLFolder, selectedItem.SecondaryModelID);
                        MDLFile   = string.Format(Strings.EquipMDLFile, "0101", selectedItem.SecondaryModelID, Info.slotAbr[Strings.Hands]);

                        offset = Helper.GetDataOffset(FFCRC.GetHash(MDLFolder), FFCRC.GetHash(MDLFile), Strings.ItemsDat);
                    }
                }
            }

            int datNum = ((offset / 8) & 0x000f) / 2;

            var MDLDatData = Helper.GetType3DecompressedData(offset, datNum, Strings.ItemsDat);

            using (BinaryReader br = new BinaryReader(new MemoryStream(MDLDatData.Item1)))
            {
                // The size of the header + (size of the mesh information block (136 bytes) * the number of meshes) + padding
                br.BaseStream.Seek(64 + 136 * MDLDatData.Item2 + 4, SeekOrigin.Begin);

                var modelStringCount = br.ReadInt32();
                var stringBlockSize  = br.ReadInt32();
                var stringBlock      = br.ReadBytes(stringBlockSize);

                var unknown = br.ReadBytes(4);

                var totalMeshCount       = br.ReadInt16();
                var attributeStringCount = br.ReadInt16();
                var meshPartsCount       = br.ReadInt16();
                var materialStringCount  = br.ReadInt16();
                var boneStringCount      = br.ReadInt16();
                var boneListCount        = br.ReadInt16();

                var unknown1 = br.ReadInt16();
                var unknown2 = br.ReadInt16();
                var unknown3 = br.ReadInt16();
                var unknown4 = br.ReadInt16();
                var unknown5 = br.ReadInt16();
                var unknown6 = br.ReadInt16();

                br.ReadBytes(10);

                var unknown7 = br.ReadInt16();

                br.ReadBytes(16);

                using (BinaryReader br1 = new BinaryReader(new MemoryStream(stringBlock)))
                {
                    br1.BaseStream.Seek(0, SeekOrigin.Begin);

                    for (int i = 0; i < attributeStringCount; i++)
                    {
                        while (br1.ReadByte() != 0)
                        {
                            //extract each atribute string here
                        }
                    }

                    for (int i = 0; i < boneStringCount; i++)
                    {
                        byte        b;
                        List <byte> boneName = new List <byte>();
                        while ((b = br1.ReadByte()) != 0)
                        {
                            boneName.Add(b);
                        }
                        string bone = Encoding.ASCII.GetString(boneName.ToArray());
                        bone = bone.Replace("\0", "");

                        boneStrings.Add(bone);
                    }

                    for (int i = 0; i < materialStringCount; i++)
                    {
                        byte        b;
                        List <byte> name = new List <byte>();
                        while ((b = br1.ReadByte()) != 0)
                        {
                            name.Add(b);
                        }
                        string material = Encoding.ASCII.GetString(name.ToArray());
                        material = material.Replace("\0", "");

                        materialStrings.Add(material);
                    }
                }

                br.ReadBytes(32 * unknown5);

                for (int i = 0; i < 3; i++)
                {
                    LevelOfDetail LoD = new LevelOfDetail();
                    LoD.MeshOffset = br.ReadInt16();
                    LoD.MeshCount  = br.ReadInt16();

                    br.ReadBytes(40);

                    LoD.VertexDataSize = br.ReadInt32();
                    LoD.IndexDataSize  = br.ReadInt32();
                    LoD.VertexOffset   = br.ReadInt32();
                    LoD.IndexOffset    = br.ReadInt32();

                    modelData.LoD.Add(LoD);
                }

                var savePos = br.BaseStream.Position;

                for (int i = 0; i < modelData.LoD.Count; i++)
                {
                    List <MeshDataInfo> meshInfoList = new List <MeshDataInfo>();

                    for (int j = 0; j < modelData.LoD[i].MeshCount; j++)
                    {
                        modelData.LoD[i].MeshList.Add(new Mesh());
                        meshInfoList.Clear();

                        br.BaseStream.Seek((i * 136) + 68, SeekOrigin.Begin);
                        var dataBlockNum = br.ReadByte();

                        while (dataBlockNum != 255)
                        {
                            MeshDataInfo meshInfo = new MeshDataInfo()
                            {
                                VertexDataBlock = dataBlockNum,
                                Offset          = br.ReadByte(),
                                DataType        = br.ReadByte(),
                                UseType         = br.ReadByte()
                            };

                            meshInfoList.Add(meshInfo);

                            br.ReadBytes(4);

                            dataBlockNum = br.ReadByte();
                        }

                        modelData.LoD[i].MeshList[j].MeshDataInfoList = meshInfoList.ToArray();
                    }
                }

                br.BaseStream.Seek(savePos, SeekOrigin.Begin);

                for (int x = 0; x < modelData.LoD.Count; x++)
                {
                    for (int i = 0; i < modelData.LoD[x].MeshCount; i++)
                    {
                        MeshInfo meshInfo = new MeshInfo()
                        {
                            VertexCount     = br.ReadInt32(),
                            IndexCount      = br.ReadInt32(),
                            MaterialNum     = br.ReadInt16(),
                            MeshPartOffset  = br.ReadInt16(),
                            MeshPartCount   = br.ReadInt16(),
                            BoneListIndex   = br.ReadInt16(),
                            IndexDataOffset = br.ReadInt32()
                        };

                        for (int j = 0; j < 3; j++)
                        {
                            meshInfo.VertexDataOffsets.Add(br.ReadInt32());
                        }

                        for (int k = 0; k < 3; k++)
                        {
                            meshInfo.VertexSizes.Add(br.ReadByte());
                        }

                        meshInfo.VertexDataBlockCount = br.ReadByte();

                        modelData.LoD[x].MeshList[i].MeshInfo = meshInfo;
                    }
                }

                br.ReadBytes(attributeStringCount * 4);
                br.ReadBytes(unknown6 * 20);

                for (int i = 0; i < modelData.LoD.Count; i++)
                {
                    foreach (var mesh in modelData.LoD[i].MeshList)
                    {
                        for (int j = 0; j < mesh.MeshInfo.MeshPartCount; j++)
                        {
                            MeshPart meshPart = new MeshPart()
                            {
                                IndexOffset = br.ReadInt32(),
                                IndexCount  = br.ReadInt32(),
                                Attributes  = br.ReadInt32(),
                                BoneOffset  = br.ReadInt16(),
                                BoneCount   = br.ReadInt16()
                            };

                            mesh.MeshPartList.Add(meshPart);
                        }
                    }
                }

                br.ReadBytes(unknown7 * 12);
                br.ReadBytes(materialStringCount * 4);
                br.ReadBytes(boneStringCount * 4);

                for (int i = 0; i < boneListCount; i++)
                {
                    Bones bones = new Bones();

                    for (int j = 0; j < 64; j++)
                    {
                        bones.BoneData.Add(br.ReadInt16());
                    }

                    bones.BoneCount = br.ReadInt32();

                    modelData.BoneSet.Add(bones);
                }

                //br.ReadBytes(unknown1 * 16);

                Dictionary <int, int>         indexMin     = new Dictionary <int, int>();
                Dictionary <int, List <int> > extraIndices = new Dictionary <int, List <int> >();
                List <ExtraIndex>             indexCounts  = new List <ExtraIndex>();

                var pCount  = 0;
                var pCount1 = 0;
                var pCount2 = 0;

                if (unknown1 > 0)
                {
                    for (int i = 0; i < unknown1; i++)
                    {
                        //not sure
                        br.ReadBytes(4);

                        //LoD[0] Extra Data Index
                        var p1 = br.ReadUInt16();

                        //LoD[1] Extra Data Index
                        var p2 = br.ReadUInt16();

                        //LoD[2] Extra Data Index
                        var p3 = br.ReadUInt16();


                        //LoD[0] Extra Data Part Count
                        var p1n = br.ReadUInt16();
                        pCount += p1n;

                        //LoD[1] Extra Data Part Count
                        var p2n = br.ReadUInt16();
                        pCount1 += p2n;

                        //LoD[2] Extra Data Part Count
                        var p3n = br.ReadUInt16();
                        pCount2 += p3n;
                    }
                }

                Dictionary <int, int> indexLoc = new Dictionary <int, int>();

                if (unknown1 > 0)
                {
                    for (int i = 0; i < modelData.LoD[0].MeshCount; i++)
                    {
                        var ido = modelData.LoD[0].MeshList[i].MeshInfo.IndexDataOffset;
                        indexLoc.Add(ido, i);
                    }
                }


                List <int>            maskCounts       = new List <int>();
                Dictionary <int, int> totalExtraCounts = new Dictionary <int, int>();
                if (unknown2 > 0)
                {
                    for (int i = 0; i < pCount; i++)
                    {
                        //Index Offset Start
                        var m1   = br.ReadInt32();
                        var iLoc = 0;
                        if (indexLoc.ContainsKey(m1))
                        {
                            iLoc = indexLoc[m1];
                        }

                        //index count
                        var mCount = br.ReadInt32();

                        //index offset in unk3
                        var mOffset = br.ReadInt32();

                        indexCounts.Add(new ExtraIndex()
                        {
                            IndexLocation = iLoc, IndexCount = mCount
                        });
                        maskCounts.Add(mCount);
                    }

                    br.ReadBytes((pCount1 + pCount2) * 12);
                }

                int totalLoD0MaskCount = 0;

                if (unknown2 > 0)
                {
                    for (int i = 0; i < pCount; i++)
                    {
                        totalLoD0MaskCount += maskCounts[i];
                    }
                }

                if (unknown3 > 0)
                {
                    var unk3Remainder = (unknown3 * 4) - (totalLoD0MaskCount * 4);

                    foreach (var ic in indexCounts)
                    {
                        HashSet <int> mIndexList = new HashSet <int>();

                        for (int i = 0; i < ic.IndexCount; i++)
                        {
                            //index its replacing? attatched to?
                            br.ReadBytes(2);
                            //extra index following last equipment index
                            var mIndex = br.ReadInt16();
                            mIndexList.Add(mIndex);

                            if (extraIndices.ContainsKey(ic.IndexLocation))
                            {
                                extraIndices[ic.IndexLocation].Add(mIndex);
                            }
                            else
                            {
                                extraIndices.Add(ic.IndexLocation, new List <int>()
                                {
                                    mIndex
                                });
                            }
                        }

                        if (totalExtraCounts.ContainsKey(ic.IndexLocation))
                        {
                            totalExtraCounts[ic.IndexLocation] += mIndexList.Count;
                        }
                        else
                        {
                            totalExtraCounts.Add(ic.IndexLocation, mIndexList.Count);
                        }
                    }
                    //the rest of unk3
                    br.ReadBytes(unk3Remainder);
                }



                if (unknown3 > 0)
                {
                    foreach (var ei in extraIndices)
                    {
                        indexMin.Add(ei.Key, ei.Value.Min());
                    }

                    extraIndexData.indexCounts      = indexCounts;
                    extraIndexData.indexMin         = indexMin;
                    extraIndexData.totalExtraCounts = totalExtraCounts;
                    extraIndexData.extraIndices     = extraIndices;

                    modelData.ExtraData = extraIndexData;
                }

                //br.ReadBytes(unknown3 * 4);

                var boneIndexSize = br.ReadInt32();

                for (int i = 0; i < boneIndexSize / 2; i++)
                {
                    modelData.BoneIndicies.Add(br.ReadInt16());
                }

                int padding = br.ReadByte();
                br.ReadBytes(padding);

                for (int i = 0; i < 4; i++)
                {
                    ModelMaterial.BoundingBox boundingBox = new ModelMaterial.BoundingBox();
                    for (int j = 0; j < 4; j++)
                    {
                        boundingBox.PointA.Add(br.ReadSingle());
                    }
                    for (int k = 0; k < 4; k++)
                    {
                        boundingBox.PointB.Add(br.ReadSingle());
                    }

                    modelData.BoundingBoxes.Add(boundingBox);
                }

                //float4x4
                for (int i = 0; i < boneStringCount; i++)
                {
                    boneTransforms.Add(br.ReadSingle());
                    boneTransforms.Add(br.ReadSingle());
                    boneTransforms.Add(br.ReadSingle());
                    boneTransforms.Add(br.ReadSingle());

                    boneTransforms.Add(br.ReadSingle());
                    boneTransforms.Add(br.ReadSingle());
                    boneTransforms.Add(br.ReadSingle());
                    boneTransforms.Add(br.ReadSingle());
                }

                for (int i = 0; i < 3; i++)
                {
                    for (int j = 0; j < modelData.LoD[i].MeshCount; j++)
                    {
                        Mesh mesh = modelData.LoD[i].MeshList[j];

                        for (int k = 0; k < mesh.MeshInfo.VertexDataBlockCount; k++)
                        {
                            br.BaseStream.Seek(modelData.LoD[i].VertexOffset + mesh.MeshInfo.VertexDataOffsets[k], SeekOrigin.Begin);

                            mesh.MeshVertexData.Add(br.ReadBytes(mesh.MeshInfo.VertexSizes[k] * mesh.MeshInfo.VertexCount));
                        }

                        br.BaseStream.Seek(modelData.LoD[i].IndexOffset + (mesh.MeshInfo.IndexDataOffset * 2), SeekOrigin.Begin);

                        mesh.IndexData = br.ReadBytes(2 * mesh.MeshInfo.IndexCount);
                    }
                }

                int vertex = 0, coordinates = 0, normals = 0, tangents = 0, colors = 0, blendWeights = 0, blendIndices = 0;

                for (int i = 0; i < modelData.LoD[0].MeshCount; i++)
                {
                    objBytes.Clear();

                    var vertexList        = new Vector3Collection();
                    var texCoordList      = new Vector2Collection();
                    var texCoordList2     = new Vector2Collection();
                    var normalList        = new Vector3Collection();
                    var tangentList       = new Vector3Collection();
                    var colorsList        = new Color4Collection();
                    var indexList         = new IntCollection();
                    var blendWeightList   = new List <float>();
                    var blendWeightList2  = new List <float[]>();
                    var blendIndicesList  = new List <int>();
                    var blendIndicesList2 = new List <int[]>();
                    var weightCounts      = new List <int>();


                    Mesh mesh = modelData.LoD[0].MeshList[i];

                    MeshDataInfo[] meshDataInfoList = mesh.MeshDataInfoList;

                    int c = 0;
                    foreach (var meshDataInfo in meshDataInfoList)
                    {
                        if (meshDataInfo.UseType == 0)
                        {
                            vertex = c;
                        }
                        else if (meshDataInfo.UseType == 1)
                        {
                            blendWeights = c;
                        }
                        else if (meshDataInfo.UseType == 2)
                        {
                            blendIndices = c;
                        }
                        else if (meshDataInfo.UseType == 3)
                        {
                            normals = c;
                        }
                        else if (meshDataInfo.UseType == 4)
                        {
                            coordinates = c;
                        }
                        else if (meshDataInfo.UseType == 6)
                        {
                            tangents = c;
                        }
                        else if (meshDataInfo.UseType == 7)
                        {
                            colors = c;
                        }

                        c++;
                    }

                    /*
                     * -----------------
                     * Vertex
                     * -----------------
                     */
                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[vertex].VertexDataBlock])))
                    {
                        for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                        {
                            br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[vertex].VertexDataBlock] + meshDataInfoList[vertex].Offset, SeekOrigin.Begin);

                            Vector3 vVector = new Vector3();
                            if (meshDataInfoList[vertex].DataType == 13 || meshDataInfoList[vertex].DataType == 14)
                            {
                                System.Half h1 = System.Half.ToHalf((ushort)br1.ReadInt16());
                                System.Half h2 = System.Half.ToHalf((ushort)br1.ReadInt16());
                                System.Half h3 = System.Half.ToHalf((ushort)br1.ReadInt16());

                                float x = HalfHelper.HalfToSingle(h1);
                                float y = HalfHelper.HalfToSingle(h2);
                                float z = HalfHelper.HalfToSingle(h3);

                                vVector = new Vector3(x, y, z);
                                objBytes.Add("v " + x.ToString("N5") + " " + y.ToString("N5") + " " + z.ToString("N5") + " ");
                            }
                            else if (meshDataInfoList[vertex].DataType == 2)
                            {
                                var x = BitConverter.ToSingle(br1.ReadBytes(4), 0);
                                var y = BitConverter.ToSingle(br1.ReadBytes(4), 0);
                                var z = BitConverter.ToSingle(br1.ReadBytes(4), 0);

                                vVector = new Vector3(x, y, z);
                                objBytes.Add("v " + x.ToString("N5") + " " + y.ToString("N5") + " " + z.ToString("N5") + " ");
                            }

                            vertexList.Add(vVector);
                        }
                    }


                    /*
                     * -----------------
                     * Blend Weight
                     * -----------------
                     */
                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[blendWeights].VertexDataBlock])))
                    {
                        for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                        {
                            br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[blendWeights].VertexDataBlock] + meshDataInfoList[blendWeights].Offset, SeekOrigin.Begin);

                            float x = br1.ReadByte() / 255.0f;
                            float y = br1.ReadByte() / 255.0f;
                            float z = br1.ReadByte() / 255.0f;
                            float w = br1.ReadByte() / 255.0f;

                            int count = 0;
                            if (x != 0)
                            {
                                blendWeightList.Add(x);
                                count++;

                                if (y != 0)
                                {
                                    blendWeightList.Add(y);
                                    count++;

                                    if (z != 0)
                                    {
                                        blendWeightList.Add(z);
                                        count++;

                                        if (w != 0)
                                        {
                                            blendWeightList.Add(w);
                                            count++;
                                        }
                                    }
                                }
                            }

                            if (count == 1)
                            {
                                blendWeightList2.Add(new float[] { x });
                            }
                            else if (count == 2)
                            {
                                blendWeightList2.Add(new float[] { x, y });
                            }
                            else if (count == 3)
                            {
                                blendWeightList2.Add(new float[] { x, y, z });
                            }
                            else if (count == 4)
                            {
                                blendWeightList2.Add(new float[] { x, y, z, w });
                            }

                            weightCounts.Add(count);
                        }
                    }


                    /*
                     * -----------------
                     * Blend Index
                     * -----------------
                     */
                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[blendIndices].VertexDataBlock])))
                    {
                        for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                        {
                            br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[blendIndices].VertexDataBlock] + meshDataInfoList[blendIndices].Offset, SeekOrigin.Begin);

                            int x = br1.ReadByte();
                            int y = br1.ReadByte();
                            int z = br1.ReadByte();
                            int w = br1.ReadByte();

                            if (weightCounts[j] == 1)
                            {
                                blendIndicesList.Add(x);
                                blendIndicesList2.Add(new int[] { x });
                            }
                            else if (weightCounts[j] == 2)
                            {
                                blendIndicesList.Add(x);
                                blendIndicesList.Add(y);
                                blendIndicesList2.Add(new int[] { x, y });
                            }
                            else if (weightCounts[j] == 3)
                            {
                                blendIndicesList.Add(x);
                                blendIndicesList.Add(y);
                                blendIndicesList.Add(z);
                                blendIndicesList2.Add(new int[] { x, y, z });
                            }
                            else if (weightCounts[j] == 4)
                            {
                                blendIndicesList.Add(x);
                                blendIndicesList.Add(y);
                                blendIndicesList.Add(z);
                                blendIndicesList.Add(w);
                                blendIndicesList2.Add(new int[] { x, y, z, w });
                            }
                        }
                    }


                    /*
                     * -----------------
                     * Texture Coordinates
                     * -----------------
                     */
                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[coordinates].VertexDataBlock])))
                    {
                        for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                        {
                            br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[coordinates].VertexDataBlock] + meshDataInfoList[coordinates].Offset, SeekOrigin.Begin);

                            float x = 0;
                            float y = 0;
                            float z = 0;
                            float w = 0;
                            if (meshDataInfoList[coordinates].DataType == 13 || meshDataInfoList[coordinates].DataType == 14)
                            {
                                var sx = (ushort)br1.ReadInt16();
                                var sy = (ushort)br1.ReadInt16();
                                var sz = (ushort)br1.ReadInt16();
                                var sw = (ushort)br1.ReadInt16();

                                var h1 = new SharpDX.Half(sx);
                                var h2 = new SharpDX.Half(sy);
                                var h3 = new SharpDX.Half(sz);
                                var h4 = new SharpDX.Half(sw);

                                x = h1;
                                y = h2;
                                z = h3;
                                w = h4;
                            }
                            else if (meshDataInfoList[coordinates].DataType == 1)
                            {
                                x = br1.ReadSingle();
                                y = br1.ReadSingle();
                            }
                            else
                            {
                                x = br1.ReadSingle();
                                y = br1.ReadSingle();
                                z = br1.ReadSingle();
                                w = br1.ReadSingle();
                            }


                            var ox = x - Math.Truncate(x);
                            var oy = y - Math.Truncate(y);

                            objBytes.Add("vt " + ox.ToString("N5") + " " + (1 - y).ToString("N5") + " ");
                            texCoordList.Add(new Vector2(x, y));
                            texCoordList2.Add(new Vector2(z, w));
                        }
                    }



                    /*
                     * -----------------
                     * Normals
                     * -----------------
                     */
                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[normals].VertexDataBlock])))
                    {
                        for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                        {
                            br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[normals].VertexDataBlock] + meshDataInfoList[normals].Offset, SeekOrigin.Begin);

                            float x = 0;
                            float y = 0;
                            float z = 0;
                            float w = 0;

                            if (meshDataInfoList[normals].DataType == 13 || meshDataInfoList[normals].DataType == 14)
                            {
                                System.Half h1 = System.Half.ToHalf((ushort)br1.ReadInt16());
                                System.Half h2 = System.Half.ToHalf((ushort)br1.ReadInt16());
                                System.Half h3 = System.Half.ToHalf((ushort)br1.ReadInt16());
                                System.Half h4 = System.Half.ToHalf((ushort)br1.ReadInt16());

                                x = HalfHelper.HalfToSingle(h1);
                                y = HalfHelper.HalfToSingle(h2);
                                z = HalfHelper.HalfToSingle(h3);
                                w = HalfHelper.HalfToSingle(h4);
                            }
                            else
                            {
                                x = br1.ReadSingle();
                                y = br1.ReadSingle();
                                z = br1.ReadSingle();
                            }

                            var nv = new Vector3(x, y, z);

                            objBytes.Add("vn " + x.ToString("N5") + " " + y.ToString("N5") + " " + z.ToString("N5") + " ");
                            normalList.Add(nv);
                        }
                    }


                    /*
                     * -----------------
                     * Tangents
                     * -----------------
                     */
                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[tangents].VertexDataBlock])))
                    {
                        for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                        {
                            br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[tangents].VertexDataBlock] + meshDataInfoList[tangents].Offset, SeekOrigin.Begin);

                            int x = br1.ReadByte();
                            int y = br1.ReadByte();
                            int z = br1.ReadByte();
                            int w = br1.ReadByte();

                            var x1 = x * 2 / 255f - 1f;
                            var y1 = y * 2 / 255f - 1f;
                            var z1 = z * 2 / 255f - 1f;
                            var w1 = w * 2 / 255f - 1f;


                            var nv = new Vector3(x1, y1, z1);

                            tangentList.Add(nv);
                        }
                    }


                    /*
                     * -----------------
                     * Vertex Color
                     * -----------------
                     */
                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[colors].VertexDataBlock])))
                    {
                        for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                        {
                            br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[colors].VertexDataBlock] + meshDataInfoList[colors].Offset, SeekOrigin.Begin);

                            int a = br1.ReadByte();
                            int r = br1.ReadByte();
                            int g = br1.ReadByte();
                            int b = br1.ReadByte();

                            colorsList.Add(new Color4(r, g, b, a));
                        }
                    }


                    /*
                     * -----------------
                     * Index
                     * -----------------
                     */
                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.IndexData)))
                    {
                        for (int j = 0; j < mesh.MeshInfo.IndexCount; j += 3)
                        {
                            int i1 = br1.ReadInt16();
                            int i2 = br1.ReadInt16();
                            int i3 = br1.ReadInt16();

                            objBytes.Add("f " + (i1 + 1) + "/" + (i1 + 1) + "/" + (i1 + 1) + " " + (i2 + 1) + "/" + (i2 + 1) + "/" + (i2 + 1) + " " + (i3 + 1) + "/" + (i3 + 1) + "/" + (i3 + 1) + " ");

                            indexList.Add(i1);
                            indexList.Add(i2);
                            indexList.Add(i3);
                        }
                    }

                    ModelMeshData modelMeshData = new ModelMeshData()
                    {
                        Vertices              = vertexList,
                        Normals               = normalList,
                        TextureCoordinates    = texCoordList,
                        TextureCoordinates2   = texCoordList2,
                        BiTangents            = tangentList,
                        Indices               = indexList,
                        VertexColors          = colorsList,
                        OBJFileData           = objBytes.ToArray(),
                        BoneStrings           = boneStrings,
                        BoneIndices           = modelData.BoneIndicies,
                        BoneTransforms        = boneTransforms,
                        BlendWeights          = blendWeightList,
                        BlendIndices          = blendIndicesList,
                        WeightCounts          = weightCounts,
                        MeshPartList          = mesh.MeshPartList,
                        BlendIndicesArrayList = blendIndicesList2,
                        BlendWeightsArrayList = blendWeightList2,
                        MaterialNum           = mesh.MeshInfo.MaterialNum,
                        MeshPartCount         = mesh.MeshInfo.MeshPartCount,
                        MeshPartOffset        = mesh.MeshInfo.MeshPartOffset
                    };

                    meshList.Add(modelMeshData);
                }
            }
        }
        /////////////////////////////////////////////////////////////////////////////////////////////
        //// below all functions taken from "Helix 3D Toolkit" MeshBuilder 
        /////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Gets a circle section (cached).
        /// </summary>
        /// <param name="thetaDiv">
        /// The number of division.
        /// </param>
        /// <param name="closed">
        /// Is the circle closed?
        /// If true, the last point will not be at the same position than the first one.
        /// </param>
        /// <returns>
        /// A circle.
        /// </returns>
        public static IList<Vector2> GetCircle(int thetaDiv, bool closed = false)
        {
            IList<Vector2> circle = null;
            // If the circle can't be found in one of the two caches
            if ((!closed && !CircleCache.TryGetValue(thetaDiv, out circle)) ||
                (closed && !ClosedCircleCache.TryGetValue(thetaDiv, out circle)))
            {
                circle = new Vector2Collection();
                // Add to the cache
                if (!closed)
                {
                    CircleCache.TryAdd(thetaDiv, circle);
                }
                else
                {
                    ClosedCircleCache.TryAdd(thetaDiv, circle);
                }
                // Determine the angle steps
                var num = closed ? thetaDiv : thetaDiv - 1;
                for (int i = 0; i < thetaDiv; i++)
                {
                    double theta = Math.PI * 2 * ((double)i / num);
                    circle.Add(new Vector2((float)Math.Cos(theta), (float)-Math.Sin(theta)));
                }
            }

            // Since Vector2Collection is not Freezable,
            // return new IList<Vector> to avoid manipulation of the Cached Values
            IList<Vector2> result = new List<Vector2>();
            foreach (var point in circle)
            {
                result.Add(new Vector2(point.X, point.Y));
            }
            return result;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="MeshBuilder"/> class.
        /// </summary>
        /// <remarks>
        /// Normal and texture coordinate generation are included.
        /// </remarks>
        public MeshBuilder(bool generateNormals = true, bool generateTexCoords = true, bool tangentSpace = false)
        {
            this.positions = new Vector3Collection();
            this.triangleIndices = new IntCollection();

            if (generateNormals)
            {
                this.normals = new Vector3Collection();
            }

            if (generateTexCoords)
            {
                this.textureCoordinates = new Vector2Collection();
            }

            if (tangentSpace)
            {
                this.tangents = new Vector3Collection();
                this.bitangents = new Vector3Collection();
            }
        }
Exemple #31
0
        private void Timer_Tick()
        {
            ++counter;
            counter %= 128;
            if (DynamicTexture)
            {
                Vector2Collection texture = null;
                if (!AnimateUVOffset)
                {
                    texture = new Vector2Collection(Model.TextureCoordinates);
                    var t0 = texture[0];
                    for (int i = 1; i < texture.Count; ++i)
                    {
                        texture[i - 1] = texture[i];
                    }
                    texture[texture.Count - 1] = t0;
                }

                context.Send((o) =>
                {
                    if (!AnimateUVOffset)
                    {
                        Model.TextureCoordinates = texture;
                        if (ReverseInnerRotation)
                        {
                            var texture1 = new Vector2Collection(texture);
                            texture1.Reverse();
                            InnerModel.TextureCoordinates = texture1;
                        }
                        else
                        {
                            InnerModel.TextureCoordinates = texture;
                        }
                    }
                    else
                    {
                        ModelMaterial.UVTransform = new UVTransform(0, Vector2.One,
                                                                    ModelMaterial.UVTransform.Translation + new Vector2(0.005f, -0.01f));
                        InnerModelMaterial.UVTransform = new UVTransform(0, Vector2.One,
                                                                         InnerModelMaterial.UVTransform.Translation + new Vector2(-0.01f, 0.005f));
                    }
                }, null);
            }
            if (DynamicVertices)
            {
                var positions = new Vector3Collection(initialPosition);
                for (int i = 0; i < positions.Count; ++i)
                {
                    var off = (float)Math.Sin(Math.PI * (float)(counter + i) / 64);
                    var p   = positions[i];
                    p           *= 0.8f + off * 0.2f;
                    positions[i] = p;
                }
                var linePositions = new Vector3Collection(positions);
                linePositions.Add(Vector3.Zero);
                //var normals =  MeshGeometryHelper.CalculateNormals(positions, initialIndicies);
                //var innerNormals =  new Vector3Collection(normals.Select(x => { return x * -1; }));
                context.Send((o) =>
                {
                    //Model.Normals = normals;
                    //InnerModel.Normals = innerNormals;
                    //Model.Positions = positions;
                    //InnerModel.Positions = positions;
                    PointModel.Positions = positions;
                    LineModel.Positions  = linePositions;
                }, null);
            }
            if (DynamicTriangles)
            {
                var indices = new IntCollection(initialIndicies);
                if (isRemoving)
                {
                    removedIndex += 3 * 8;
                    if (removedIndex >= initialIndicies.Count)
                    {
                        removedIndex = initialIndicies.Count;
                        isRemoving   = false;
                    }
                }
                else
                {
                    removedIndex -= 3 * 8;
                    if (removedIndex <= 0)
                    {
                        isRemoving   = true;
                        removedIndex = 0;
                    }
                }
                indices.RemoveRange(0, removedIndex);
                context.Send((o) =>
                {
                    Model.Indices      = indices;
                    InnerModel.Indices = indices;
                }, null);
            }
            if (DynamicTexture)
            {
                var colors = new Color4Collection(PointModel.Colors);
                for (int k = 0; k < 10; ++k)
                {
                    var c = colors[colors.Count - 1];
                    for (int i = colors.Count - 1; i > 0; --i)
                    {
                        colors[i] = colors[i - 1];
                    }
                    colors[0] = c;
                }
                var lineColors = new Color4Collection(LineModel.Colors);
                for (int k = 0; k < 10; ++k)
                {
                    var c = lineColors[colors.Count - 2];
                    for (int i = lineColors.Count - 2; i > 0; --i)
                    {
                        lineColors[i] = lineColors[i - 1];
                    }
                    lineColors[0] = c;
                }
                context.Send((o) =>
                {
                    PointModel.Colors = colors;
                    LineModel.Colors  = lineColors;
                }, null);
            }
        }
Exemple #32
0
 private void Timer_Tick(object sender, EventArgs e)
 {
     if (DynamicTexture)
     {
         var texture = new Vector2Collection(Model.TextureCoordinates);
         for (int i = 1; i < Model.TextureCoordinates.Count; ++i)
         {
             texture[i - 1] = Model.TextureCoordinates[i];
         }
         texture[texture.Count - 1] = Model.TextureCoordinates[0];
         Model.TextureCoordinates   = texture;
         if (ReverseInnerRotation)
         {
             var texture1 = new Vector2Collection(texture);
             texture1.Reverse();
             InnerModel.TextureCoordinates = texture1;
         }
         else
         {
             InnerModel.TextureCoordinates = texture;
         }
     }
     if (DynamicVertices)
     {
         var positions = new Vector3Collection(initialPosition);
         for (int i = 0; i < positions.Count; ++i)
         {
             positions[i] = positions[i] * (float)rnd.Next(95, 105) / 100;
         }
         Model.Normals        = MeshGeometryHelper.CalculateNormals(positions, Model.Indices);
         InnerModel.Normals   = new Vector3Collection(Model.Normals.Select(x => { return(x * -1); }));
         Model.Positions      = positions;
         InnerModel.Positions = positions;
         //Alternative implementation
         //Floor.DisablePropertyChangedEvent = true;
         //Floor.Positions = positions;
         //Floor.CalculateNormals();
         //Floor.DisablePropertyChangedEvent = false;
         //Floor.UpdateVertex();
     }
     if (DynamicTriangles)
     {
         var indices = new IntCollection(initialIndicies);
         if (isRemoving)
         {
             removedIndex += 3 * 8;
             if (removedIndex >= initialIndicies.Count)
             {
                 removedIndex = initialIndicies.Count;
                 isRemoving   = false;
             }
         }
         else
         {
             removedIndex -= 3 * 8;
             if (removedIndex <= 0)
             {
                 isRemoving   = true;
                 removedIndex = 0;
             }
         }
         indices.RemoveRange(0, removedIndex);
         Model.Indices      = indices;
         InnerModel.Indices = indices;
     }
 }
Exemple #33
0
        /// <summary>
        /// Reads a triangular mesh.
        /// </summary>
        /// <param name="reader">
        /// The reader.
        /// </param>
        /// <param name="chunkSize">
        /// The chunk size.
        /// </param>
        private void ReadTriangularMesh(BinaryReader reader, int chunkSize)
        {
            MeshBuilder       builder            = new MeshBuilder();
            int               bytesRead          = 6;
            Vector3Collection positions          = null;
            IntCollection     faces              = null;
            Vector2Collection textureCoordinates = null;
            List <FaceSet>    facesets           = null;
            IntCollection     triangleIndices    = null;
            Vector3Collection normals            = null;
            //Matrix matrix = Matrix.Identity;
            Vector3Collection tangents   = null;
            Vector3Collection bitangents = null;
            List <Matrix>     transforms = new List <Matrix>();

            while (bytesRead < chunkSize)
            {
                ChunkID id   = this.ReadChunkId(reader);
                int     size = this.ReadChunkSize(reader);
                bytesRead += size;
                switch (id)
                {
                case ChunkID.TRI_VERTEXL:
                    positions = this.ReadVertexList(reader);
                    break;

                case ChunkID.TRI_FACEL1:
                    faces    = ReadFaceList(reader);
                    size    -= (faces.Count / 3 * 8) + 2;
                    facesets = this.ReadFaceSets(reader, size - 6);
                    break;

                case ChunkID.TRI_TEXCOORD:
                    textureCoordinates = ReadTexCoords(reader);
                    break;

                case ChunkID.TRI_LOCAL:
                    transforms.Add(this.ReadTransformation(reader));
                    break;

                default:
                    this.ReadData(reader, size - 6);
                    break;
                }
            }

            if (faces == null)
            {
                //no faces defined?? return...
                return;
            }

            if (facesets == null || facesets.Count == 0)
            {
                triangleIndices = faces;
                CreateMesh(positions, textureCoordinates, triangleIndices, transforms, out normals, out tangents, out bitangents, new PhongMaterial()
                {
                    Name              = "Gray",
                    AmbientColor      = new Color4(0.1f, 0.1f, 0.1f, 1.0f),
                    DiffuseColor      = new Color4(0.254902f, 0.254902f, 0.254902f, 1.0f),
                    SpecularColor     = new Color4(0.0225f, 0.0225f, 0.0225f, 1.0f),
                    EmissiveColor     = new Color4(0.0f, 0.0f, 0.0f, 1.0f),
                    SpecularShininess = 12.8f,
                });
                //Add default get and setter
            }
            else
            {
                foreach (var fm in facesets)
                {
                    triangleIndices = ConvertFaceIndices(fm.Faces, faces);
                    MaterialCore mat = null;
                    if (this.materials.ContainsKey(fm.Name))
                    {
                        mat = this.materials[fm.Name];
                    }
                    CreateMesh(positions, textureCoordinates, triangleIndices, transforms, out normals, out tangents, out bitangents, mat);
                }
            }
        }
        /////////////////////////////////////////////////////////////////////////////////////////////
        //// below all functions taken from "Helix 3D Toolkit" MeshBuilder 
        /////////////////////////////////////////////////////////////////////////////////////////////


        /// <summary>
        /// Gets a circle section (cached).
        /// </summary>
        /// <param name="thetaDiv">
        /// The number of division.
        /// </param>
        /// <returns>
        /// A circle.
        /// </returns>
        public static IList<Vector2> GetCircle(int thetaDiv)
        {
            IList<Vector2> circle;
            if (!CircleCache.TryGetValue(thetaDiv, out circle))
            {
                circle = new Vector2Collection();
                CircleCache.Add(thetaDiv, circle);
                for (int i = 0; i < thetaDiv; i++)
                {
                    double theta = Math.PI * 2 * ((double)i / (thetaDiv - 1));
                    circle.Add(new Vector2((float)Math.Cos(theta), -(float)Math.Sin(theta)));
                }
            }

            return circle;
        }
        /// <summary>
        /// Adds an arrow to the mesh.
        /// </summary>
        /// <param name="point1">
        /// The start point.
        /// </param>
        /// <param name="point2">
        /// The end point.
        /// </param>
        /// <param name="diameter">
        /// The diameter of the arrow cylinder.
        /// </param>
        /// <param name="headLength">
        /// Length of the head (relative to diameter).
        /// </param>
        /// <param name="thetaDiv">
        /// The number of divisions around the arrow.
        /// </param>
        public void AddArrow(Vector3 point1, Vector3 point2, double diameter, double headLength = 3, int thetaDiv = 18)
        {
            var dir = point2 - point1;
            var length = dir.Length();
            var r = (float)diameter / 2;

            var pc = new Vector2Collection
                {
                    new Vector2(0, 0),
                    new Vector2(0, r),
                    new Vector2(length - (float)(diameter * headLength), r),
                    new Vector2(length - (float)(diameter * headLength), r * 2),
                    new Vector2(length, 0)
                };

            this.AddRevolvedGeometry(pc, point1, dir, thetaDiv);
        }
        private static void AppendSphere(Vector3 center, double radius, int thetaSteps, int phiSteps,
            out Vector3Collection positions, out Vector3Collection normals, out Vector2Collection textureCoordinates, out IntCollection triangleIndices)
        {
            positions = new Vector3Collection();
            normals = new Vector3Collection();
            textureCoordinates = new Vector2Collection();
            triangleIndices = new IntCollection();

            double dt = DegToRad(360.0) / thetaSteps;
            double dp = DegToRad(180.0) / phiSteps;

            for (int pi = 0; pi <= phiSteps; pi++)
            {
                double phi = pi * dp;
                for (int ti = 0; ti <= thetaSteps; ti++)
                {
                    // we want to start the mesh on the x axis
                    double theta = ti * dt;

                    positions.Add(GetPosition(theta, phi, radius) + center);
                    normals.Add(GetNormal(theta, phi));
                    textureCoordinates.Add(GetTextureCoordinate(theta, phi));
                }
            }

            for (int pi = 0; pi < phiSteps; pi++)
            {
                for (int ti = 0; ti < thetaSteps; ti++)
                {
                    int x0 = ti;
                    int x1 = ti + 1;
                    int y0 = pi * (thetaSteps + 1);
                    int y1 = (pi + 1) * (thetaSteps + 1);

                    triangleIndices.Add(x0 + y0);
                    triangleIndices.Add(x0 + y1);
                    triangleIndices.Add(x1 + y0);

                    triangleIndices.Add(x1 + y0);
                    triangleIndices.Add(x0 + y1);
                    triangleIndices.Add(x1 + y1);
                }
            }
        }
        /// <summary>
        /// Makes sure no triangles share the same vertex.
        /// </summary>
        private void NoSharedVertices()
        {
            var p = new Vector3Collection();
            var ti = new IntCollection();
            Vector3Collection n = null;
            if (this.normals != null)
            {
                n = new Vector3Collection();
            }

            Vector2Collection tc = null;
            if (this.textureCoordinates != null)
            {
                tc = new Vector2Collection();
            }

            for (int i = 0; i < this.triangleIndices.Count; i += 3)
            {
                int i0 = i;
                int i1 = i + 1;
                int i2 = i + 2;
                int index0 = this.triangleIndices[i0];
                int index1 = this.triangleIndices[i1];
                int index2 = this.triangleIndices[i2];
                var p0 = this.positions[index0];
                var p1 = this.positions[index1];
                var p2 = this.positions[index2];
                p.Add(p0);
                p.Add(p1);
                p.Add(p2);
                ti.Add(i0);
                ti.Add(i1);
                ti.Add(i2);
                if (n != null)
                {
                    n.Add(this.normals[index0]);
                    n.Add(this.normals[index1]);
                    n.Add(this.normals[index2]);
                }

                if (tc != null)
                {
                    tc.Add(this.textureCoordinates[index0]);
                    tc.Add(this.textureCoordinates[index1]);
                    tc.Add(this.textureCoordinates[index2]);
                }
            }

            this.positions = p;
            this.triangleIndices = ti;
            this.normals = n;
            this.textureCoordinates = tc;
        }
        /// <summary>
        /// Chamfers the specified corner (experimental code).
        /// </summary>
        /// <param name="p">
        /// The corner point.
        /// </param>
        /// <param name="d">
        /// The chamfer distance.
        /// </param>
        /// <param name="eps">
        /// The corner search limit distance.
        /// </param>
        /// <param name="chamferPoints">
        /// If this parameter is provided, the collection will be filled with the generated chamfer points.
        /// </param>
        public void ChamferCorner(Vector3 p, double d, double eps = 1e-6, IList<Vector3> chamferPoints = null)
        {
            this.NoSharedVertices();

            this.normals = null;
            this.textureCoordinates = null;

            var cornerNormal = this.FindCornerNormal(p, eps);

            var newCornerPoint = p - (cornerNormal * (float)d);
            int index0 = this.positions.Count;
            this.positions.Add(newCornerPoint);

            var plane = new Plane3D(newCornerPoint, cornerNormal);

            int ntri = this.triangleIndices.Count;

            for (int i = 0; i < ntri; i += 3)
            {
                int i0 = i;
                int i1 = i + 1;
                int i2 = i + 2;
                var p0 = this.positions[this.triangleIndices[i0]];
                var p1 = this.positions[this.triangleIndices[i1]];
                var p2 = this.positions[this.triangleIndices[i2]];
                var d0 = (p - p0).LengthSquared();
                var d1 = (p - p1).LengthSquared();
                var d2 = (p - p2).LengthSquared();
                var mind = Math.Min(d0, Math.Min(d1, d2));
                if (mind > eps)
                {
                    continue;
                }

                if (d1 < eps)
                {
                    i0 = i + 1;
                    i1 = i + 2;
                    i2 = i;
                }

                if (d2 < eps)
                {
                    i0 = i + 2;
                    i1 = i;
                    i2 = i + 1;
                }

                p0 = this.positions[this.triangleIndices[i0]];
                p1 = this.positions[this.triangleIndices[i1]];
                p2 = this.positions[this.triangleIndices[i2]];

                // p0 is the corner vertex (at index i0)
                // find the intersections between the chamfer plane and the two edges connected to the corner
                var line1 = new Ray(p0, p1 - p0);
                var line2 = new Ray(p0, p2 - p0);
                Vector3 p01, p02;

                if (!plane.Intersects(ref line1, out p01))
                {
                    continue;
                }

                if (!plane.Intersects(ref line2, out p02))
                {
                    continue;
                }

                if (chamferPoints != null)
                {
                    // add the chamfered points
                    if (!chamferPoints.Contains(p01))
                    {
                        chamferPoints.Add(p01);
                    }

                    if (!chamferPoints.Contains(p02))
                    {
                        chamferPoints.Add(p02);
                    }
                }

                int i01 = i0;

                // change the original triangle to use the first chamfer point
                this.positions[this.triangleIndices[i01]] = p01;

                int i02 = this.positions.Count;
                this.positions.Add(p02);

                // add a new triangle for the other chamfer point
                this.triangleIndices.Add(i01);
                this.triangleIndices.Add(i2);
                this.triangleIndices.Add(i02);

                // add a triangle connecting the chamfer points and the new corner point
                this.triangleIndices.Add(index0);
                this.triangleIndices.Add(i01);
                this.triangleIndices.Add(i02);
            }

            this.NoSharedVertices();
        }
 private  Vector2Collection ReadTexCoords(BinaryReader reader)
 {
   int size = reader.ReadUInt16();
   var pts = new Vector2Collection();
   for(int i=0;i< size; i++)
   {
     float x = reader.ReadSingle();
     float y = reader.ReadSingle();
     pts.Add(new Vector2(x, y));
   }
   return pts;
 }
        /// <summary>
        /// Adds a (possibly truncated) cone.
        /// </summary>
        /// <param name="origin">
        /// The origin.
        /// </param>
        /// <param name="direction">
        /// The direction (normalization not required).
        /// </param>
        /// <param name="baseRadius">
        /// The base radius.
        /// </param>
        /// <param name="topRadius">
        /// The top radius.
        /// </param>
        /// <param name="height">
        /// The height.
        /// </param>
        /// <param name="baseCap">
        /// Include a base cap if set to <c>true</c> .
        /// </param>
        /// <param name="topCap">
        /// Include the top cap if set to <c>true</c> .
        /// </param>
        /// <param name="thetaDiv">
        /// The number of divisions around the cone.
        /// </param>
        /// <remarks>
        /// See http://en.wikipedia.org/wiki/Cone_(geometry).
        /// </remarks>
        public void AddCone(
            Vector3 origin,
            Vector3 direction,
            double baseRadius,
            double topRadius,
            double height,
            bool baseCap,
            bool topCap,
            int thetaDiv)
        {
            var pc = new Vector2Collection();
            if (baseCap)
            {
                pc.Add(new Vector2(0, 0));
            }

            pc.Add(new Vector2(0, (float)baseRadius));
            pc.Add(new Vector2((float)height, (float)topRadius));
            if (topCap)
            {
                pc.Add(new Vector2((float)height, 0));
            }

            this.AddRevolvedGeometry(pc, origin, direction, thetaDiv);
        }
        private IList <Object3D> Load(BinaryReader reader)
        {
            var name         = reader.ReadCMO_wchar();
            int numMaterials = (int)reader.ReadUInt32();
            var materials    = new List <Tuple <PhongMaterial, IList <string> > >(numMaterials);

            for (int i = 0; i < numMaterials; ++i)
            {
                var material = new PhongMaterial
                {
                    Name              = reader.ReadCMO_wchar(),
                    AmbientColor      = reader.ReadStructure <Color4>(),
                    DiffuseColor      = reader.ReadStructure <Color4>(),
                    SpecularColor     = reader.ReadStructure <Color4>(),
                    SpecularShininess = reader.ReadSingle(),
                    EmissiveColor     = reader.ReadStructure <Color4>()
                };
                var uvTransform = reader.ReadStructure <Matrix>();
                if (uvTransform == Matrix.Zero)
                {
                    uvTransform = Matrix.Identity;
                }
                uvTransform.Decompose(out var s, out var r, out var tra);
                material.UVTransform = new UVTransform(r.Angle, new Vector2(s.X, s.Y), new Vector2(tra.X, tra.Y));
                var pixelShaderName = reader.ReadCMO_wchar();//Not used
                var textures        = new List <string>();
                for (int t = 0; t < MaxTextures; ++t)
                {
                    textures.Add(reader.ReadCMO_wchar());
                }
                materials.Add(new Tuple <PhongMaterial, IList <string> >(material, textures));
            }

            //      BYTE - 1 if there is skeletal animation data present

            // is there skeletal animation data present?
            bool isAnimationData = reader.ReadByte() == 1;
            //      UINT - SubMesh count
            //      { [SubMesh count]
            //          SubMesh structure
            //      }

            // load sub meshes if any

            var mesh         = new MeshGeometry3D();
            int subMeshCount = (int)reader.ReadUInt32();

            var subMesh = new List <SubMesh>(subMeshCount);

            for (int i = 0; i < subMeshCount; i++)
            {
                subMesh.Add(reader.ReadStructure <SubMesh>());
            }

            //      UINT - IB Count
            //      { [IB Count]
            //          UINT - Number of USHORTs in IB
            //          USHORT[] - Array of indices
            //      }

            // load triangle indices
            int indexBufferCount = (int)reader.ReadUInt32();
            var indices          = new List <ushort[]>(indexBufferCount);

            for (var i = 0; i < indexBufferCount; i++)
            {
                indices.Add(reader.ReadUInt16((int)reader.ReadUInt32()));
            }

            //      UINT - VB Count
            //      { [VB Count]
            //          UINT - Number of verts in VB
            //          Vertex[] - Array of vertices
            //      }

            // load vertex positions
            int vertexBufferCount = (int)reader.ReadUInt32();
            var vertexBuffers     = new List <Vertex[]>(vertexBufferCount);

            for (var i = 0; i < vertexBufferCount; i++)
            {
                vertexBuffers.Add(reader.ReadStructure <Vertex>((int)reader.ReadUInt32()));
            }
            //      UINT - Skinning VB Count
            //      { [Skinning VB Count]
            //          UINT - Number of verts in Skinning VB
            //          SkinningVertex[] - Array of skinning verts
            //      }

            // load vertex skinning parameters
            int skinningVertexBufferCount = (int)reader.ReadUInt32();
            var skinningVertexBuffers     = new List <SkinningVertex[]>(skinningVertexBufferCount);

            for (var i = 0; i < skinningVertexBufferCount; i++)
            {
                skinningVertexBuffers.Add(reader.ReadStructure <SkinningVertex>((int)reader.ReadUInt32()));
            }
            // load mesh extent
            var            extent             = reader.ReadStructure <MeshExtent>();
            var            animationHierarchy = new AnimationHierarchy();
            IList <string> boneNames          = null;

            if (isAnimationData)
            {
                //      UINT - Bone count
                //      { [Bone count]
                //          UINT - Length of bone name
                //          wchar_t[] - Bone name (if length > 0)
                //          Bone structure
                //      }
                int boneCount = (int)reader.ReadUInt32();
                boneNames = new string[boneCount];
                for (var i = 0; i < boneCount; i++)
                {
                    boneNames[i] = reader.ReadCMO_wchar();
                    animationHierarchy.Bones.Add(reader.ReadStructure <BoneStruct>());
                }

                //      UINT - Animation clip count
                //      { [Animation clip count]
                //          UINT - Length of clip name
                //          wchar_t[] - Clip name (if length > 0)
                //          float - Start time
                //          float - End time
                //          UINT - Keyframe count
                //          { [Keyframe count]
                //              Keyframe structure
                //          }
                //      }
                int animationCount = (int)reader.ReadUInt32();
                for (var i = 0; i < animationCount; i++)
                {
                    Animation animation     = new Animation(AnimationType.Keyframe);
                    string    animationName = reader.ReadCMO_wchar();
                    animation.StartTime = reader.ReadSingle();
                    animation.EndTime   = reader.ReadSingle();
                    animation.Name      = animationName;
                    int keyframeCount = (int)reader.ReadUInt32();
                    for (var j = 0; j < keyframeCount; j++)
                    {
                        var keyframe = reader.ReadStructure <KeyframeCMO>();
                        keyframe.Transform.Decompose(out var s, out var q, out var t);
                        animation.Keyframes.Add(new Keyframe()
                        {
                            Translation = t, Rotation = q, Scale = s, Time = keyframe.Time
                        });
                    }
                    animationHierarchy.Animations.Add(animation.Name, animation);
                    if (!UniqueAnimations.ContainsKey(animation.Name))
                    {
                        UniqueAnimations.Add(animation.Name, new List <Guid>());
                    }
                    UniqueAnimations[animation.Name].Add(animation.GUID);
                }
            }
            var obj3Ds = new List <Object3D>(subMeshCount);

            for (int i = 0; i < subMesh.Count; ++i)
            {
                var sub              = subMesh[i];
                var material         = materials.Count == 0 ? new PhongMaterial() : materials[(int)sub.MaterialIndex].Item1;
                var vertexCollection = new Vector3Collection(vertexBuffers[(int)sub.VertexDataIndex].Select(x => x.Position));
                var normal           = new Vector3Collection(vertexBuffers[(int)sub.VertexDataIndex].Select(x => x.Normal));
                var tex              = new Vector2Collection(vertexBuffers[(int)sub.VertexDataIndex].Select(x => x.UV));
                var tangent          = new Vector3Collection(vertexBuffers[(int)sub.VertexDataIndex].Select(x => x.Tangent.ToVector3()));
                var biTangent        = new Vector3Collection(normal.Zip(tangent, (x, y) => { return(Vector3.Cross(x, y)); }));
                var indexCollection  = new IntCollection(indices[(int)sub.IndexDataIndex].Select(x => (int)x));
                var meshGeo          = new MeshGeometry3D()
                {
                    Positions          = vertexCollection,
                    Indices            = indexCollection, Normals = normal,
                    Tangents           = tangent, BiTangents = biTangent,
                    TextureCoordinates = tex
                };
                if (isAnimationData)
                {
                    var boneskinmesh = new BoneSkinnedMeshGeometry3D(meshGeo);
                    boneskinmesh.VertexBoneIds = new List <BoneIds>(skinningVertexBuffers[(int)sub.VertexDataIndex]
                                                                    .Select(x => new BoneIds()
                    {
                        Bone1   = (int)x.BoneIndex0,
                        Bone2   = (int)x.BoneIndex1,
                        Bone3   = (int)x.BoneIndex2,
                        Bone4   = (int)x.BoneIndex3,
                        Weights = new Vector4(x.BoneWeight0, x.BoneWeight1, x.BoneWeight2, x.BoneWeight3),
                    }));
                    meshGeo = boneskinmesh;
                }
                //Todo Load textures
                obj3Ds.Add(new Object3D()
                {
                    Geometry = meshGeo, Material = material, Name = name
                });
                animationHierarchy.Meshes.Add(obj3Ds.Last());
            }
            AnimationHierarchy.Add(animationHierarchy);
            return(obj3Ds);
        }
        /// <summary>
        /// Gets a circle segment section.
        /// </summary>
        /// <param name="thetaDiv">The number of division.</param>
        /// <param name="totalAngle">The angle of the circle segment.</param>
        /// <param name="angleOffset">The angle-offset to use.</param>
        /// <returns>
        /// A circle segment.
        /// </returns>
        public static IList<Vector2> GetCircleSegment(int thetaDiv, float totalAngle = 2 * (float)Math.PI, float angleOffset = 0)
        {
            IList <Vector2> circleSegment;
            circleSegment = new Vector2Collection();
            for (int i = 0; i < thetaDiv; i++)
            {
                double theta = totalAngle * ((double)i / (thetaDiv - 1)) + angleOffset;
                circleSegment.Add(new Vector2((float)Math.Cos(theta), (float)Math.Sin(theta)));
            }

            return circleSegment;
        }
        public static MeshGeometry3D Merge(params MeshGeometry3D[] meshes)
        {
            var positions = new Vector3Collection();
            var indices = new IntCollection();

            var normals = meshes.All(x => x.Normals != null) ? new Vector3Collection() : null;
            var colors = meshes.All(x => x.Colors != null) ? new Color4Collection() : null;
            var textureCoods = meshes.All(x => x.TextureCoordinates != null) ? new Vector2Collection() : null;
            var tangents = meshes.All(x => x.Tangents != null) ? new Vector3Collection() : null;
            var bitangents = meshes.All(x => x.BiTangents != null) ? new Vector3Collection() : null;

            int index = 0;
            foreach (var part in meshes)
            {
                for (int i = 0; i < part.Positions.Count; i++)
                {
                    positions.Add(part.Positions[i]);
                }

                for (int i = 0; i < part.Indices.Count; i++)
                {
                    indices.Add(index + part.Indices[i]);
                }

                index += part.Indices.Count;
            }

            if (normals != null)
            {
                normals = new Vector3Collection(meshes.SelectMany(x => x.Normals));
            }

            if (colors != null)
            {
                colors = new Color4Collection(meshes.SelectMany(x => x.Colors));
            }

            if (textureCoods != null)
            {
                textureCoods = new Vector2Collection(meshes.SelectMany(x => x.TextureCoordinates));
            }

            if (tangents != null)
            {
                tangents = new Vector3Collection(meshes.SelectMany(x => x.Tangents));
            }

            if (bitangents != null)
            {
                bitangents = new Vector3Collection(meshes.SelectMany(x => x.BiTangents));
            }

            var mesh = new MeshGeometry3D()
            {
                Positions = positions,
                Indices = indices,
            };

            mesh.Normals = normals;
            mesh.Colors = colors;
            mesh.TextureCoordinates = textureCoods;
            mesh.Tangents = tangents;
            mesh.BiTangents = bitangents;

            return mesh;
        }
        /// <summary>
        /// Adds a (possibly hollow) pipe.
        /// </summary>
        /// <param name="point1">
        /// The start point.
        /// </param>
        /// <param name="point2">
        /// The end point.
        /// </param>
        /// <param name="innerDiameter">
        /// The inner diameter.
        /// </param>
        /// <param name="diameter">
        /// The outer diameter.
        /// </param>
        /// <param name="thetaDiv">
        /// The number of divisions around the pipe.
        /// </param>
        public void AddPipe(Vector3 point1, Vector3 point2, double innerDiameter, double diameter, int thetaDiv)
        {
            var dir = point2 - point1;

            double height = dir.Length();
            dir.Normalize();

            var pc = new Vector2Collection
                {
                    new Vector2(0, (float)innerDiameter / 2),
                    new Vector2(0, (float)diameter / 2),
                    new Vector2((float)height, (float)diameter / 2),
                    new Vector2((float)height, (float)innerDiameter / 2)
                };

            if (innerDiameter > 0)
            {
                // Add the inner surface
                pc.Add(new Vector2(0, (float)innerDiameter / 2));
            }

            this.AddRevolvedGeometry(pc, point1, dir, thetaDiv);
        }
Exemple #45
0
 public static bool Contains(this Vector2Collection vectors, double[] expectedVector)
 {
     return(vectors.Any(vector => Math.Abs((float)expectedVector[0] - vector.X) < float.Epsilon &&
                        Math.Abs((float)expectedVector[1] - vector.Y) < float.Epsilon));
 }
 public TexturedMeshBinder(Autodesk.Dynamo.MeshToolkit.Mesh mesh, string textureFileName, Vector2Collection textureCoordinates)
     : this(mesh, DynaShapeDisplay.DefaultMeshFaceColor, textureFileName, textureCoordinates)
 {
 }
    /// <summary>
    /// Create a Mesh, with found props
    /// </summary>
    /// <param name="positions"></param>
    /// <param name="textureCoordinates"></param>
    /// <param name="triangleIndices"></param>
    /// <param name="normals"></param>
    /// <param name="tangents"></param>
    /// <param name="bitangents"></param>
    /// <param name="material"></param>
    private void CreateMesh(Vector3Collection positions, Vector2Collection textureCoordinates, IntCollection triangleIndices, out Vector3Collection normals, out Vector3Collection tangents, out Vector3Collection bitangents,Material material)
    {
      ComputeNormals(positions, triangleIndices, out normals);
      if (textureCoordinates == null)
      {
        textureCoordinates = new Vector2Collection();
        foreach(var pos in positions)
        {
          textureCoordinates.Add(Vector2.One);
        }
      } 
      MeshBuilder.ComputeTangents(positions, normals, textureCoordinates, triangleIndices, out tangents, out bitangents);
      MeshGeometry3D mesh = new MeshGeometry3D()
      {
        Positions = positions,
        Normals = normals,
        TextureCoordinates = textureCoordinates,
        Indices = triangleIndices,
        Tangents = tangents,
        BiTangents = bitangents

      };
      Object3D ob3d = new Object3D();
      ob3d.Geometry = mesh;
      ob3d.Material = material;
      ob3d.Transform = Matrix.Identity;
      ob3d.Name = "Default";
      this.obGroup.Add(ob3d);
    }