Пример #1
0
 private void CanCompute_CornerAngles() =>
 this.FlatSquare.Corners.ForEach(
     corner =>
 {
     var angle = MeshGeometry.Angle(corner);
     Assert.True(Math.Abs(angle - 0.5 * Math.PI) < Settings.Tolerance);
 });
Пример #2
0
            public override void Finish(bool cancel)
            {
                if (!cancel)
                {
                    //calculate mesh in space position
                    var points = MeshGeometry.GetPointPositions();
                    if (points.Length != 0)
                    {
                        var position = Vector3.Zero;
                        foreach (var point in points)
                        {
                            position += point;
                        }
                        position /= points.Length;
                        CreatingObject.Transform = new Transform(position, Quaternion.Identity);
                    }

                    //attach points to the mesh in space
                    foreach (var point in MeshGeometry.GetPoints())
                    {
                        Component_ObjectInSpace_Utility.Attach(CreatingObject, point);
                    }

                    //select meshin space and points
                    var toSelect = new List <Component>();
                    toSelect.Add(CreatingObject);
                    //toSelect.AddRange( points );
                    EditorAPI.SelectComponentsInMainObjectsWindow(DocumentWindow, toSelect.ToArray());

                    //update mesh
                    MeshGeometry?.ShouldRecompileMesh();
                }

                base.Finish(cancel);
            }
Пример #3
0
 private void CanCompute_EdgeLengths() =>
 this.FlatSquare.Edges.ForEach(
     edge =>
 {
     var length = MeshGeometry.Length(edge);
     Assert.True(Math.Abs(length - 1) < Settings.Tolerance);
 });
Пример #4
0
        public static Mesh LddRoundEdgeMeshToAssimp(MeshGeometry geometry)
        {
            var assimpMesh   = new Mesh(Assimp.PrimitiveType.Triangle);
            int indexCounter = 0;

            foreach (var tri in geometry.Triangles)
            {
                foreach (var idx in tri.Indices)
                {
                    assimpMesh.Vertices.Add(idx.Vertex.Position.ToAssimp());
                    assimpMesh.Normals.Add(idx.Vertex.Normal.ToAssimp());
                    for (int i = 0; i < 6; i++)
                    {
                        var uvCoord = idx.RoundEdgeData.Coords[i];
                        if (RoundEdgeData.EmptyCoord != uvCoord)
                        {
                            uvCoord.X = Math.Abs(uvCoord.X) - 100f;
                        }
                        //uvCoord /= 10f;
                        assimpMesh.TextureCoordinateChannels[i].Add(new Vector3D(uvCoord.X, uvCoord.Y, 0));
                    }
                }

                assimpMesh.Faces.Add(new Face(new int[] { indexCounter++, indexCounter++, indexCounter++ }));
            }

            return(assimpMesh);
        }
Пример #5
0
        public GeometryModel3D CreateGeometryModel3D()
        {
            try
            {
                if (!this.CheckAccess())
                {
                    var ret = default(GeometryModel3D);
                    this.Dispatcher.Invoke(new Action(delegate { ret = CreateGeometryModel3D(); }));
                    return(ret);
                }

                {
                    if (MeshGeometry == null)
                    {
                        return(null);
                    }

                    var meshGeometry3D = MeshGeometry.CreateMeshGeometry3D();
                    if (meshGeometry3D == null)
                    {
                        return(null);
                    }

                    var ret = new GeometryModel3D(meshGeometry3D, new DiffuseMaterial(new SolidColorBrush(MaterialColor)));
                    ret.BackMaterial = (MaterialColor == BackMaterialColor) ? ret.Material : new DiffuseMaterial(new SolidColorBrush(BackMaterialColor));
                    return(ret);
                }
            }
            catch (System.Exception)
            {
                return(null);
            }
        }
Пример #6
0
        private void GenerateMesh(VoxelGrid grid)
        {
            this.EnqueueWorkerJob(() =>
            {
                //Thread.Sleep(750);
                var voxels   = this.grid.Data;
                var vertices = new List <VertexPositionTextureNormal>(voxels.XLength * voxels.YLength * voxels.ZLength);
                var indices  = new List <ushort>(voxels.XLength * voxels.YLength * voxels.ZLength);

                MeshGenerator.GenerateGridMesh(voxels, (voxel, side, quad) =>
                {
                    var textureOffset = GetTexCoords(voxel, side);
                    indices.Add((ushort)(vertices.Count + 0));
                    indices.Add((ushort)(vertices.Count + 1));
                    indices.Add((ushort)(vertices.Count + 3));
                    indices.Add((ushort)(vertices.Count + 1));
                    indices.Add((ushort)(vertices.Count + 2));
                    indices.Add((ushort)(vertices.Count + 3));
                    vertices.Add(new VertexPositionTextureNormal(quad.A, (textureOffset + new Vector2(0, 128)) / new Vector2(1024, 2048), quad.Normal));
                    vertices.Add(new VertexPositionTextureNormal(quad.B, (textureOffset + new Vector2(0, 0)) / new Vector2(1024, 2048), quad.Normal));
                    vertices.Add(new VertexPositionTextureNormal(quad.C, (textureOffset + new Vector2(128, 0)) / new Vector2(1024, 2048), quad.Normal));
                    vertices.Add(new VertexPositionTextureNormal(quad.D, (textureOffset + new Vector2(128, 128)) / new Vector2(1024, 2048), quad.Normal));
                });
                if (_meshGeometry == null)
                {
                    _meshGeometry = new MeshGeometry();
                }
                _meshGeometry.UpdateMesh(vertices.ToArray(), indices.ToArray());
            });
        }
Пример #7
0
        /// <summary>
        ///     Computes a geodesic on a mesh given a starting point and an initial direction.
        ///     Returns true if successfull and false if something went wrong.
        /// </summary>
        /// <param name="meshPoint">Point.</param>
        /// <param name="vector">Direction.</param>
        /// <param name="mesh">Mesh.</param>
        /// <param name="maxIter">Maximum iterations.</param>
        /// <param name="geodesic">Geodesic curves.</param>
        /// <returns>True if successful.</returns>
        public static bool StartDir(
            MeshPoint meshPoint,
            Vector3d vector,
            Mesh mesh,
            int maxIter,
            out List <Point3d> geodesic)
        {
            // Get initial face on the mesh
            var initialFace = mesh.Faces[meshPoint.FaceIndex];

            // Start iteration
            // Create variables for current iteration step
            var thisFace      = initialFace;
            var thisPoint     = new Point3d();
            var thisDirection = vector;

            var iter       = 0;
            var geodPoints = new List <Point3d>();

            do
            {
                var ray = new Ray(thisPoint, thisDirection);

                // Find intersection between ray and boundary
                Intersect3D.RayFacePerimeter(ray, thisFace, out var nextPoint, out var halfEdge);

                // Intersection method should check for correct direction using sign of dot product

                // Add point to pointlist
                geodPoints.Add(nextPoint);

                // Walk to next face
                var nextFace = halfEdge.Twin.Face;

                // Flip vector to next face
                var perpVector = Vector3d.CrossProduct(
                    thisDirection,
                    MeshGeometry.FaceNormal(thisFace));
                var nextVector = Vector3d.CrossProduct(
                    MeshGeometry.FaceNormal(nextFace),
                    perpVector);

                // Assign iteration variables to current
                thisPoint     = nextPoint;
                thisFace      = nextFace;
                thisDirection = nextVector;

                // Increase counter
                iter++;
            } while (iter < maxIter);

            // Assign outputs
            geodesic = geodPoints;
            return(true);
        }
Пример #8
0
 private void CanCompute_VertexNormal() =>
 this.FlatTriangle.Vertices.ForEach(
     vertex =>
 {
     var normal = MeshGeometry.VertexNormalAngleWeighted(vertex);
     Assert.Equal(Vector3d.UnitZ, normal);
     normal = MeshGeometry.VertexNormalEquallyWeighted(vertex);
     Assert.Equal(Vector3d.UnitZ, normal);
     normal = MeshGeometry.VertexNormalAreaWeighted(vertex);
     Assert.Equal(Vector3d.UnitZ, normal);
 });
        public MeshGeometry ConstructFrom(Mesh mesh, Transform[] bones)
        {
            var             result       = new MeshGeometry();
            List <Vector3d> verticesList = GetVerticesList(mesh.vertices);
            List <Tuple <int, int, int> > trianglesList = MeshDataHelper.GetTrianglesList(mesh.triangles);
            Dictionary <string, Dictionary <int, float> > bonesWeights = GetBonesWeights(mesh.boneWeights, bones);

            result.vertices     = verticesList;
            result.triangles    = trianglesList;
            result.bonesWeights = bonesWeights;
            result.normals      = MeshDataHelper.GetNormals(mesh.normals);
            result.uvMaps       = MeshDataHelper.GetUvMaps(mesh);
            return(result);
        }
Пример #10
0
        public void Reset()
        {
            _currentMeshGeometry = null;
            _currentClump = null;
            _currentPrototype = null;
            _currentPrelight = default(Color);
            _currentTransform = new Matrix4();
            _currentMaterial = new Material();

            _clumpStack.Clear();
            _materialStack.Clear();
            _transformStack.Clear();

            _model = new Model();
        }
Пример #11
0
        private static Node CreateMeshNode(Scene scene, MeshGeometry geometry, string name, int materialIndex, MeshExportOptions exportOptions)
        {
            var meshNode = new Node()
            {
                Name = name
            };

            var aMesh = exportOptions.IncludeRoundEdgeData ?
                        LddRoundEdgeMeshToAssimp(geometry) : LddMeshToAssimp(geometry);

            aMesh.MaterialIndex = materialIndex;
            meshNode.MeshIndices.Add(scene.MeshCount);
            scene.Meshes.Add(aMesh);

            return(meshNode);
        }
Пример #12
0
            //

            public CreationModePolyhedron(DocumentWindowWithViewport documentWindow, Component creatingObject)
                : base(documentWindow, creatingObject)
            {
                var position = CreatingObject.TransformV.Position;

                if (CalculatePointPosition(documentWindow.Viewport, out var position2, out _))
                {
                    position = position2;
                }

                var point = MeshGeometry.CreateComponent <Component_MeshGeometry_PolygonBasedPolyhedron_Point>(enabled: false);

                point.Name      = MeshGeometry.Components.GetUniqueName("Point", false, 1);
                point.Transform = new Transform(position, Quaternion.Identity);
                point.Enabled   = true;
            }
Пример #13
0
        private static void SetShaderData(MESH_FILE file, MESH_DATA data, MeshGeometry mesh)
        {
            for (int i = 0; i < data.Indices.Length; i++)
            {
                var index = data.Indices[i];

                if (index.AverageNormalIndex >= 0 && index.AverageNormalIndex < file.AverageNormals.Length)
                {
                    mesh.Indices[i].AverageNormal = file.AverageNormals[index.AverageNormalIndex];
                }

                if (file.GetShaderDataFromOffset(index.REShaderOffset, out ROUNDEDGE_SHADER_DATA shaderData))
                {
                    mesh.Indices[i].RoundEdgeData = new RoundEdgeData(shaderData.Coords.Take(6).ToArray());
                }
            }
        }
Пример #14
0
            protected override void OnUpdateBeforeOutput(Viewport viewport)
            {
                base.OnUpdateBeforeOutput(viewport);

                lastStartPointRectangle = null;

                var points = MeshGeometry.GetPointPositions();

                if (!heightStage && points.Length > 2)
                {
                    if (viewport.CameraSettings.ProjectToScreenCoordinates(points[0], out var screenPosition))
                    {
                        var pos = points[0];

                        Vector2 maxSize     = new Vector2(20, 20);
                        Vector2 minSize     = new Vector2(5, 5);
                        double  maxDistance = 100;

                        double distance = (pos - viewport.CameraSettings.Position).Length();
                        if (distance < maxDistance)
                        {
                            Vector2 sizeInPixels = Vector2.Lerp(maxSize, minSize, distance / maxDistance);
                            Vector2 screenSize   = sizeInPixels / viewport.SizeInPixels.ToVector2();
                            screenSize *= 1.5;

                            var rect = new Rectangle(screenPosition - screenSize * .5, screenPosition + screenSize * .5);

                            ColorValue color;
                            if (!viewport.MouseRelativeMode && rect.Contains(viewport.MousePosition))
                            {
                                color = new ColorValue(1, 1, 0, 0.5);
                            }
                            else
                            {
                                color = new ColorValue(1, 1, 1, 0.3);
                            }

                            viewport.CanvasRenderer.AddQuad(rect, color);

                            lastStartPointRectangle = rect;
                        }
                    }
                }
            }
Пример #15
0
        public static Mesh LddMeshToAssimp(MeshGeometry geometry)
        {
            var  assimpMesh = new Mesh(Assimp.PrimitiveType.Triangle);
            bool isTextured = geometry.IsTextured;

            foreach (var v in geometry.Vertices)
            {
                assimpMesh.Vertices.Add(v.Position.ToAssimp());
                assimpMesh.Normals.Add(v.Normal.ToAssimp());
                if (isTextured)
                {
                    assimpMesh.TextureCoordinateChannels[0].Add(new Vector3D(v.TexCoord.X, v.TexCoord.Y, 0));
                }
            }

            if (geometry.IsFlexible)
            {
                var boneIDs  = geometry.Vertices.SelectMany(x => x.BoneWeights).Select(y => y.BoneID).Distinct().ToList();
                var boneDict = new Dictionary <int, Bone>();
                boneIDs.ForEach(x => boneDict.Add(x, new Bone()
                {
                    Name = GetBoneName(x)
                }));

                for (int vIdx = 0; vIdx < geometry.VertexCount; vIdx++)
                {
                    foreach (var bw in geometry.Vertices[vIdx].BoneWeights)
                    {
                        boneDict[bw.BoneID].VertexWeights.Add(new VertexWeight(vIdx, bw.Weight));
                    }
                }

                assimpMesh.Bones.AddRange(boneDict.Values);
            }

            int[] indices = geometry.GetTriangleIndices();

            for (int i = 0; i < indices.Length; i += 3)
            {
                assimpMesh.Faces.Add(new Face(new int[] { indices[i], indices[i + 1], indices[i + 2] }));
            }

            return(assimpMesh);
        }
        protected override MeshGeometry DeriveMeshGeometryData(Mesh mesh, Transform[] bones)
        {
            var parentChannel = bones[0];
            var result        = new MeshGeometry();
            var verticesList  = mesh.vertices.Select(x => new Vector3d(x.x, x.y, x.z)).ToList();
            Dictionary <string, Dictionary <int, float> > bonesWeights = new Dictionary <string, Dictionary <int, float> >();

            Dictionary <int, float> verticesBoneWeights = new Dictionary <int, float>();

            for (int i = 0; i < verticesList.Count; i++)
            {
                verticesBoneWeights.Add(i, 1.0f);
            }

            bonesWeights.Add(parentChannel.name, verticesBoneWeights);

            result.vertices     = verticesList;
            result.triangles    = MeshDataHelper.GetTrianglesList(mesh.triangles);
            result.bonesWeights = bonesWeights;
            result.normals      = MeshDataHelper.GetNormals(mesh.normals);
            result.uvMaps       = MeshDataHelper.GetUvMaps(mesh);
            return(result);
        }
Пример #17
0
        private unsafe void DebugMesh(MeshGeometry mesh)
        {
            System.Console.WriteLine("---------Positions-----------------");
            UnmanagedArray <Vertex> array = mesh.Vertexes;

            for (int i = 0; i < array.Length; i++)
            {
                Vertex v = array[i];
                System.Console.WriteLine(string.Format("({0},{1},{2})", v.X, v.Y, v.Z));
            }
            System.Console.WriteLine("---------Colors-----------------");
            UnmanagedArray <ColorF> colors = mesh.VertexColors;

            for (int i = 0; i < colors.Length; i++)
            {
                ColorF c = colors[i];
                System.Console.WriteLine(string.Format("({0},{1},{2},{3})", c.R, c.G, c.B, c.A));
            }
            System.Console.WriteLine("---------visibles-----------------");
            UnmanagedArray <float> visibles = mesh.Visibles;

            for (int i = 0; i < visibles.Length; i++)
            {
                float c = visibles[i];
                System.Console.WriteLine(string.Format("({0})", c));
            }

            System.Console.WriteLine("---------TriangleTrip-----------------");
            UnmanagedArray <uint> triangles = mesh.StripTriangles;

            for (int i = 0; i < triangles.Length; i++)
            {
                uint t = triangles[i];
                System.Console.WriteLine(string.Format("({0})", t));
            }
        }
Пример #18
0
        public AnimatedExportObjectModel convert(ExportableModel r3AnimatedMesh)
        {
            AnimatedExportObjectModel result = new AnimatedExportObjectModel();

            result.Name = r3AnimatedMesh.gameObject.name;
            Dictionary <string, BoneBindPose> bonesBindPoses =
                GetBonesBindPoseTransforms(r3AnimatedMesh).
                ToDictionary(
                    x => x.Key,
                    x => new BoneBindPose(
                        x.Key,
                        x.Value.position,
                        x.Value.rotation,
                        x.Value.scale
                        ));
            MeshGeometry   meshGeometry   = DeriveMeshGeometryData(GetMesh(r3AnimatedMesh), GetBonesTransforms(r3AnimatedMesh));
            TransformModel transformModel = GetTransformModel(r3AnimatedMesh.transform);

            result.bindBonePoses = bonesBindPoses;
            result.meshGeometry  = meshGeometry;
            result.transform     = transformModel;
            result.materials     = GetMaterials(r3AnimatedMesh);
            return(result);
        }
Пример #19
0
        private void Create3DObject(object sender, EventArgs e)
        {
            try
            {
                int     nx        = System.Convert.ToInt32(tbNX.Text);
                int     ny        = System.Convert.ToInt32(tbNY.Text);
                int     nz        = System.Convert.ToInt32(tbNZ.Text);
                float   step      = System.Convert.ToSingle(tbColorIndicatorStep.Text);
                float   radius    = System.Convert.ToSingle(this.tbRadius.Text);
                int     dimenSize = nx * ny * nz;
                float   dx        = System.Convert.ToSingle(this.tbDX.Text);
                float   dy        = System.Convert.ToSingle(this.gbDY.Text);
                float   dz        = System.Convert.ToSingle(this.tbDZ.Text);
                float[] dxArray   = initArray(dimenSize, dx);
                float[] dyArray   = initArray(dimenSize, dy);
                float[] dzArray   = initArray(dimenSize, dz);
                // use CatesianGridderSource to fill HexahedronGridderElement's content.
                CatesianGridderSource source = new CatesianGridderSource()
                {
                    NX = nx, NY = ny, NZ = nz, DX = dxArray, DY = dyArray, DZ = dzArray,
                };
                source.IBlocks = GridBlockHelper.CreateBlockCoords(nx);
                source.JBlocks = GridBlockHelper.CreateBlockCoords(ny);
                source.KBlocks = GridBlockHelper.CreateBlockCoords(nz);


                //DemoPointSpriteGridderSource source = new DemoPointSpriteGridderSource() { NX = nx, NY = ny, NZ = nz, };

                ///模拟获得网格属性
                int minValue = 100;
                int maxValue = 10000;
                step = (maxValue * 1.0f - minValue * 1.0f) / 10;
                int[]   gridIndexes;
                float[] gridValues;
                //设置色标的范围
                this.scientificVisual3DControl.SetColorIndicator(minValue, maxValue, step);
                //获得每个网格上的属性值
                HexahedronGridderHelper.RandomValue(source.DimenSize, minValue, maxValue, out gridIndexes, out gridValues);
                ColorF[] colors = new ColorF[source.DimenSize];
                for (int i = 0; i < colors.Length; i++)
                {
                    colors[i] = (ColorF)this.scientificVisual3DControl.MapToColor(gridValues[i]);
                }

                // use HexahedronGridderElement
                DateTime     t0   = DateTime.Now;
                MeshGeometry mesh = HexahedronGridderHelper.CreateMesh(source);
                DateTime     t1   = DateTime.Now;
                TimeSpan     ts1  = t1 - t0;

                mesh.VertexColors = HexahedronGridderHelper.FromColors(source, gridIndexes, colors, mesh.Visibles);
                //this.DebugMesh(mesh);

                HexahedronGridderElement gridderElement = new HexahedronGridderElement(source, this.scientificVisual3DControl.Scene.CurrentCamera);
                gridderElement.renderWireframe = false;
                //method1
                //gridderElement.Initialize(this.scientificVisual3DControl.OpenGL);

                //method2
                gridderElement.Initialize(this.scientificVisual3DControl.OpenGL, mesh);
                DateTime t2 = DateTime.Now;

                //gridderElement.SetBoundingBox(mesh.Min, mesh.Max);

                //// use PointSpriteGridderElement
                //PointSpriteMesh mesh = PointSpriteGridderElementHelper.CreateMesh(source);
                //mesh.ColorArray = PointSpriteGridderElementHelper.FromColors(source, gridIndexes, colors, mesh.VisibleArray);

                //PointSpriteGridderElement gridderElement = new PointSpriteGridderElement(source, this.scientificVisual3DControl.Scene.CurrentCamera);
                //gridderElement.Initialize(this.scientificVisual3DControl.OpenGL, mesh);
                ////DebugMesh(mesh);

                //


                gridderElement.Name = string.Format("element {0}", elementCounter++);
                this.scientificVisual3DControl.AddModelElement(gridderElement);
                DateTime t3 = DateTime.Now;
                // update ModelContainer's BoundingBox.
                BoundingBox boundingBox = this.scientificVisual3DControl.ModelContainer.BoundingBox;
                if (this.scientificVisual3DControl.ModelContainer.Children.Count > 1)
                {
                    boundingBox.Extend(mesh.Min);
                    boundingBox.Extend(mesh.Max);
                }
                else
                {
                    boundingBox.SetBounds(mesh.Min, mesh.Max);
                }
                //boundingBox.Expand();

                // update ViewType to UserView.
                this.scientificVisual3DControl.ViewType = ViewTypes.UserView;
                mesh.Dispose();

                StringBuilder msgBuilder = new StringBuilder();
                msgBuilder.AppendLine(String.Format("create mesh in {0} secs", (t1 - t0).TotalSeconds));
                msgBuilder.AppendLine(String.Format("init SceneElement in {0} secs", (t2 - t1).TotalSeconds));
                msgBuilder.AppendLine(String.Format("total load in {0} secs", (t2 - t0).TotalSeconds));
                String msg = msgBuilder.ToString();
                MessageBox.Show(msg, "Summary", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception error)
            {
                MessageBox.Show(error.ToString());
            }
        }
Пример #20
0
        private void TrySetTextureProperties(aiMaterial outMat, Dictionary<string, LayeredTexture> layeredTextures,
            string propName,
            aiTextureType target, MeshGeometry mesh)
        {
            LayeredTexture it;
            if (!layeredTextures.TryGetValue(propName, out it))
            {
                return;
            }
            var tex = it.Texture;

            var path = tex.RelativeFilename;
            outMat.TextureSlotCollection[target].TextureBase = path;

            var uvTrafo = new AssimpSharp.UVTransform();
            uvTrafo.Scaling = tex.UVScaling;
            uvTrafo.Translation = tex.UVTranslation;
            outMat.TextureSlotCollection[target].UVTransformBase = uvTrafo;

            var props = tex.Props;
            var uvIndex = 0;
            bool ok;
            var uvSet = PropertyHelper.PropertyGet<string>(props, "UVSet", out ok);
            if (ok)
            {
                if (uvSet != "default" && !string.IsNullOrEmpty(uvSet))
                {
                    var matIndex = Materials.IndexOf(outMat);
                    uvIndex = -1;
                    if (mesh == null)
                    {
                        foreach (var v in MeshesConverted)
                        {
                            var mesh_ = v.Key as MeshGeometry;
                            if (mesh_ == null)
                            {
                                continue;
                            }
                            var mats = mesh_.MaterialIndices;
                            if (!mats.Contains(matIndex))
                            {
                                continue;
                            }
                            int index = -1;
                            for (int i = 0; i < aiMesh.AI_MAX_NUMBER_OF_TEXTURECOORDS; i++)
                            {
                                if (mesh.GetTextureCoords(i).Count == 0)
                                {
                                    break;
                                }
                                var name = mesh.GetTextureCoordChannelName(i);
                                if (name == uvSet)
                                {
                                    index = i;
                                    break;
                                }
                            }
                            if (index == -1)
                            {
                                FBXImporter.LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material");
                                continue;
                            }
                            if (uvIndex == -1)
                            {
                                uvIndex = index;
                            }
                            else
                            {
                                FBXImporter.LogWarn("the UV channel named " + uvSet +
                                " appears at different positions in meshes, results will be wrong");
                            }
                        }
                    }
                    else
                    {
                        int index = -1;
                        for (int i = 0; i < aiMesh.AI_MAX_NUMBER_OF_TEXTURECOORDS; i++)
                        {
                            if (mesh.GetTextureCoords(i).Count == 0)
                            {
                                break;
                            }
                            var name = mesh.GetTextureCoordChannelName(i);
                            if (name == uvSet)
                            {
                                index = i;
                                break;
                            }
                        }
                        if (index == -1)
                        {
                            FBXImporter.LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material");
                        }
                        if (uvIndex == -1)
                        {
                            uvIndex = index;
                        }
                    }
                    if (uvIndex == -1)
                    {
                        FBXImporter.LogWarn("failed to resolve UV channel " + uvSet + ", using first UV channel");
                        uvIndex = 0;
                    }
                }
            }
            outMat.TextureSlotCollection[target].UVWSrcBase = uvIndex;
        }
Пример #21
0
        private int ConvertMaterial(Material material, MeshGeometry mesh)
        {
            var props = material.Props;

            // generate empty output material
            var outMat = new aiMaterial();
            this.MaterialsConverted[material] = this.Materials.Count;

            this.Materials.Add(outMat);

            // stip Material:: prefix
            string name = material.Name;
            if (name.Substring(0, 10) == "Material::")
            {
                name = name.Substring(10);
            }

            // set material name if not empty - this could happen
            // and there should be no key for it in this case.
            if (name.Length > 0)
            {
                outMat.Name = name;
            }

            // shading stuff and colors
            SetShadingPropertiesCommon(outMat, props);

            // texture assignments
            SetTextureProperties(outMat, material.Textures, mesh);
            SetTextureProperties(outMat, material.LayeredTextures, mesh);

            return this.Materials.Count - 1;
        }
Пример #22
0
            protected override bool OnMouseDown(Viewport viewport, EMouseButtons button)
            {
                if (button == EMouseButtons.Left)
                {
                    bool overStartPoint = !heightStage && lastStartPointRectangle.HasValue && lastStartPointRectangle.Value.Contains(viewport.MousePosition);

                    if (heightStage)
                    {
                        Finish(false);
                        return(true);
                    }
                    else if (overStartPoint)
                    {
                        HeightStageStart(viewport);
                        return(true);
                    }
                    else
                    {
                        var points = MeshGeometry.GetPoints();

                        if (!viewport.MouseRelativeMode)
                        {
                            if (points.Length >= 3)
                            {
                                var plane = MeshGeometry.GetPolygonPlaneByPoints();
                                var ray   = viewport.CameraSettings.GetRayByScreenCoordinates(viewport.MousePosition);

                                if (plane.Intersects(ray, out double scale))
                                {
                                    var position = ray.GetPointOnRay(scale);

                                    var point = MeshGeometry.CreateComponent <Component_MeshGeometry_PolygonBasedPolyhedron_Point>(enabled: false);
                                    point.Name      = MeshGeometry.Components.GetUniqueName("Point", false, 1);
                                    point.Transform = new Transform(position, Quaternion.Identity);
                                    point.Enabled   = true;

                                    return(true);
                                }
                            }
                            else
                            {
                                if (CalculatePointPosition(viewport, out var position, out var collidedWith))
                                {
                                    var point = MeshGeometry.CreateComponent <Component_MeshGeometry_PolygonBasedPolyhedron_Point>(enabled: false);
                                    point.Name      = MeshGeometry.Components.GetUniqueName("Point", false, 1);
                                    point.Transform = new Transform(position, Quaternion.Identity);
                                    point.Enabled   = true;

                                    //detect Clockwise
                                    var points2 = MeshGeometry.GetPointPositions();
                                    if (points2.Length == 3)
                                    {
                                        var normal = Plane.FromPoints(points2[0], points2[1], points2[2]).Normal;

                                        var d1 = (points2[0] - viewport.CameraSettings.Position).Length();
                                        var d2 = ((points2[0] + normal) - viewport.CameraSettings.Position).Length();

                                        if (d1 < d2)
                                        {
                                            MeshGeometry.Clockwise = true;
                                        }
                                    }

                                    return(true);
                                }
                            }
                        }
                    }
                }

                return(false);
            }
Пример #23
0
 public void SetGeometry(MeshGeometry geometry)
 {
     Geometry = geometry;
 }
Пример #24
0
        private List<int> ConvertMeshMultiMaterial(MeshGeometry mesh, Model model, Matrix nodeGlobalTransform)
        {
            var mindices = mesh.MaterialIndices;
            Debug.Assert(mindices.Count > 0);

            var had = new HashSet<int>();
            var indices = new List<int>();

            foreach (var index in mindices)
            {
                if (!had.Contains(index))
                {
                    indices.Add(ConvertMeshMultiMaterial(mesh, model, index, nodeGlobalTransform));
                    had.Add(index);
                }
            }
            return indices;
        }
Пример #25
0
        private int ConvertMeshSingleMaterial(MeshGeometry mesh, Model model, Matrix nodeGlobalTransform)
        {
            var mindices = mesh.MaterialIndices;
            var outMesh = SetupEmptyMesh(mesh);

            var vertices = mesh.Vertices;
            var faces = mesh.FaceIndexCounts;

            // copy vertices
            outMesh.NumVertices = vertices.Count;
            outMesh.Vertices = new Vector3[vertices.Count];
            vertices.CopyTo(outMesh.Vertices);

            // generate dummy faces
            outMesh.NumFaces = faces.Count;
            var fac = outMesh.Faces = new AssimpSharp.Face[faces.Count];
            for(int i=0; i<faces.Count; i++)
            {
                fac[i] = new AssimpSharp.Face();
            }

            int cursor = 0;
            var facIndex = 0;
            foreach(var pcount in faces)
            {
                var f = fac[facIndex++];
                f.Indices = new int[pcount];
                switch(pcount)
                {
                    case 1:
                        outMesh.PrimitiveTypes |= AssimpSharp.PrimitiveType.Point;
                        break;
                    case 2:
                        outMesh.PrimitiveTypes |= AssimpSharp.PrimitiveType.Line;
                        break;
                    case 3:
                        outMesh.PrimitiveTypes |= AssimpSharp.PrimitiveType.Triangle;
                        break;
                    default:
                        outMesh.PrimitiveTypes |= AssimpSharp.PrimitiveType.Polygon;
                        break;
                }
                for(int i=0; i<pcount; ++i)
                {
                    f.Indices[i] = cursor++;
                }
            }

            // copy normals
            var normals = mesh.Normals;
            if (normals.Count > 0)
            {
                Debug.Assert(normals.Count == vertices.Count);
                outMesh.Normals = new Vector3[vertices.Count];
                normals.CopyTo(outMesh.Normals);
            }

            // copy tangents - assimp requires both tangents and bitangents (binormals)
            // to be present, or neither of them. Compute binormals from normals
            // and tangents if needed.
            var tangents = mesh.Tangents;
            var binormals = mesh.Binormals;
            if (tangents.Count > 0)
            {
                var tempBinormals = new List<Vector3>();
                if (binormals.Count == 0)
                {
                    if (normals.Count > 0)
                    {
                        tempBinormals = new List<Vector3>(normals.Count);
                        for(int i=0; i<tangents.Count; i++)
                        {
                            tempBinormals.Add(Vector3.Cross(normals[i], tangents[i]));
                        }
                        binormals.Clear();
                        for(int i=0; i<tempBinormals.Count; i++)
                        {
                            binormals.Add(tempBinormals[i]);
                        }
                    }
                    else
                    {
                        binormals = null;
                    }
                }
                if (binormals != null)
                {
                    Debug.Assert(tangents.Count == vertices.Count);
                    Debug.Assert(binormals.Count == vertices.Count);

                    outMesh.Tangents = new Vector3[vertices.Count];
                    tangents.CopyTo(outMesh.Tangents);

                    outMesh.Bitangents = new Vector3[vertices.Count];
                    binormals.CopyTo(outMesh.Bitangents);
                }
            }

            // copy texture coords
            for (int i=0; i<Mesh.AI_MAX_NUMBER_OF_TEXTURECOORDS; i++)
            {
                var uvs = mesh.GetTextureCoords(i);
                if (uvs.Count == 0)
                {
                    break;
                }

                var outUv = outMesh.TextureCoords[i] = new Vector3[vertices.Count];
                for(int j=0; j<uvs.Count; j++)
                {
                    outUv[j] = new Vector3(uvs[j].X, uvs[j].Y, 0);
                }
            }

            // copy vertex colors
            for (int i = 0; i < aiMesh.AI_MAX_NUMBER_OF_COLOR_SETS; ++i)
            {
                var colors = mesh.GetVertexColors(i);
                if (colors.Count == 0)
                {
                    break;
                }
                outMesh.Colors[i] = new Color4[vertices.Count];
                colors.CopyTo(outMesh.Colors[i]);
            }

            if (!Doc.Settings.ReadMaterials || mindices.Count == 0)
            {
                //FBXImporter.LogError("no material assigned to mesh, setting default material");
                outMesh.MaterialIndex = GetDefaultMaterial();
            }
            else
            {
                ConvertMaterialForMesh(outMesh, model, mesh, mindices[0]);
            }

            if (Doc.Settings.ReadWeights && mesh.DeformerSkin != null)
            {
                ConvertWeights(outMesh, model, mesh, nodeGlobalTransform, NO_MATERIAL_SEPARATION);
            }

            return Meshes.Count - 1;
        }
Пример #26
0
        /// <summary>
        /// Initialize our basic model
        /// </summary>
        /// <param name="device">Direct3D device for use</param>
        /// <param name="texMgr">Texture manager from which to load texture data</param>
        /// <param name="filename">Filename of the ASSIMP resource we would like to load (see ASSIMP documentation for supported formats)</param>
        /// <param name="texturePath">Texture path - base path for textures used by the ASSIMP model</param>
        public BasicModel(Device device, TextureManager texMgr, string filename, string texturePath)
        {
            _subsets = new List<MeshGeometry.Subset>();
            _vertices = new List<BasicEffectVertex>();
            _indices = new List<ushort>();
            DiffuseMapSRV = new List<ShaderResourceView>();
            NormalMapSRV = new List<ShaderResourceView>();
            Materials = new List<Lighting.Material>();
            _modelMesh = new MeshGeometry();

            var importer = new AssimpContext();
            if (!importer.IsImportFormatSupported(Path.GetExtension(filename)))
            {
                throw new ArgumentException($"Model format {Path.GetExtension(filename)} is not supported! Cannot load {filename}", "Outside Engine");
            }
            var model = importer.ImportFile(filename, PostProcessSteps.GenerateSmoothNormals | PostProcessSteps.CalculateTangentSpace);
            #if DEBUG
            var logStream = new ConsoleLogStream();
            logStream.Attach();
            #endif

            foreach (var mesh in model.Meshes)
            {
                //
                // Vertex processing
                //
                var verts = new List<BasicEffectVertex>();
                var subset = new MeshGeometry.Subset
                {
                    VertexCount = mesh.VertexCount,
                    VertexStart = _vertices.Count,
                    FaceStart = _indices.Count / 3,
                    FaceCount = mesh.FaceCount
                };
                _subsets.Add(subset);

                // TODO KAM: Process bounding box corners

                for (var i = 0; i < mesh.VertexCount; ++i)
                {
                    Vector3 pos = mesh.HasVertices ? mesh.Vertices[i].ToVector3() : new Vector3();

                    var norml = mesh.HasNormals ? mesh.Normals[i].ToVector3() : new Vector3();
                    var texC = mesh.HasTextureCoords(0) ? mesh.TextureCoordinateChannels[0][i].ToVector3() : new Vector3();
                    var tan = mesh.HasTangentBasis ? mesh.Tangents[i].ToVector3() : new Vector3();
                    var v = new BasicEffectVertex(pos, norml, new Vector2(texC.X, texC.Y));
                    verts.Add(v);
                }

                _vertices.AddRange(verts);

                var indices = mesh.GetIndices().Select(i => (ushort)(i + (uint)subset.VertexStart)).ToList();
                _indices.AddRange(indices);

                //
                // Material processing
                //
                var mat = model.Materials[mesh.MaterialIndex];
                var material = mat.ToMaterial();

                Materials.Add(material);
                TextureSlot diffuseSlot;
                mat.GetMaterialTexture(TextureType.Diffuse, 0, out diffuseSlot);
                var diffusePath = diffuseSlot.FilePath;
                if (Path.GetExtension(diffusePath) == ".tga")
                {
                    throw new InvalidDataException("Cannot use TGA files for textures with DirectX. Sorry about that.");
                }

                if (!string.IsNullOrEmpty(diffusePath))
                {
                    DiffuseMapSRV.Add(texMgr.GetTexture(Path.Combine(texturePath, diffusePath)));
                }

                TextureSlot normalSlot;
                mat.GetMaterialTexture(TextureType.Normals, 0, out normalSlot);
                var normalPath = normalSlot.FilePath;
                if (!string.IsNullOrEmpty(normalPath))
                {
                    NormalMapSRV.Add(texMgr.GetTexture(Path.Combine(texturePath, normalPath)));
                }
                else
                {
                    var normalExt = Path.GetExtension(diffusePath);
                    normalPath = Path.GetFileNameWithoutExtension(diffusePath) + "_nmap" + normalExt;
                    NormalMapSRV.Add(texMgr.GetTexture(Path.Combine(texturePath, normalPath)));
                }
            }

            _modelMesh.SetSubsetTable(_subsets);
            _modelMesh.SetVertices(device, _vertices);
            _modelMesh.SetIndices(device, _indices);
        }
Пример #27
0
        private static MESH_DATA SerializeMeshGeometry(MESH_FILE file, ShaderDataHelper shaderData, MeshGeometry meshGeometry)
        {
            var meshData = MESH_DATA.Create(meshGeometry.VertexCount, meshGeometry.IndexCount, file.IsTextured, file.IsFlexible);

            var vertIndexer = new ListIndexer <Vertex>(meshGeometry.Vertices);

            for (int i = 0; i < meshGeometry.Vertices.Count; i++)
            {
                var vert = meshGeometry.Vertices[i];
                meshData.Positions[i] = vert.Position;
                meshData.Normals[i]   = vert.Normal;

                if (file.IsTextured)
                {
                    meshData.UVs[i] = meshGeometry.IsTextured ? vert.TexCoord : new Vector2(0f);
                }

                if (file.IsFlexible && vert.BoneWeights.Any())
                {
                    var boneWeights = vert.BoneWeights.Select(x => new MESH_BONE_WEIGHT {
                        BoneID = x.BoneID, Weight = x.Weight
                    });
                    meshData.Bones[i] = new MESH_BONE_MAPPING(boneWeights);
                }
            }

            for (int i = 0; i < meshGeometry.Indices.Count; i++)
            {
                var idx = meshGeometry.Indices[i];
                meshData.Indices[i].VertexIndex = vertIndexer.IndexOf(idx.Vertex);

                meshData.Indices[i].AverageNormalIndex = shaderData.AvgNormals.IndexOf(idx.AverageNormal);

                int reIdx = shaderData.RoundEdgeData.IndexOf(idx.RoundEdgeData);

                int reOffset = reIdx * 12 + ((int)Math.Floor(reIdx / 21d) * 4);

                meshData.Indices[i].REShaderOffset = reOffset;
            }

            return(meshData);
        }
        /// <summary>
        ///   The geometry object has a list of polygon faces.  
        ///   Take those, and use them to populate the subMesh object.
        ///   TODO: Do I need to compact those first?
        ///         Do I need to build consolidated sets of points that the face indexes can refer to?
        /// </summary>
        /// <param name="subMesh">the Axiom SubMesh object that we will populate</param>
        /// <param name="geometry">the geometry information that contains the polygons</param>
        /// <param name="indexType">the type of face index (16 bit or 32 bit)</param>
        protected void ProcessFaces( SubMeshInfo subMeshInfo, MeshGeometry geometry,
                                    IndexType indexType )
        {
            SubMesh subMesh = m_AxiomMesh.CreateSubMesh( subMeshInfo.name );
            subMesh.MaterialName = subMeshInfo.material;

            int[ , ] data = geometry.GetFaceData();
            subMesh.indexData.indexStart = 0;
            subMesh.indexData.indexCount = data.GetLength( 0 ) * data.GetLength( 1 );

            HardwareIndexBuffer idxBuffer = null;

            // create the index buffer
            idxBuffer =
                HardwareBufferManager.Instance.CreateIndexBuffer( indexType,
                                                                subMesh.indexData.indexCount,
                                                                m_AxiomMesh.IndexBufferUsage,
                                                                m_AxiomMesh.UseIndexShadowBuffer );

            HWBuffer.FillBuffer( idxBuffer, subMesh.indexData.indexCount, indexType, data );

            // save the index buffer
            subMesh.indexData.indexBuffer = idxBuffer;
        }
Пример #29
0
        /// <summary>
        /// Compute the intersection between a mesh face perimeter and a ray tangent to the face.
        /// </summary>
        /// <param name="ray">The tangent ray.</param>
        /// <param name="face">The mesh face.</param>
        /// <param name="result">The resulting intersection point.</param>
        /// <param name="halfEdge">The half-edge on where the intersection lies.</param>
        /// <returns>Intersection result.</returns>
        public static ISRayFacePerimeter RayFacePerimeter(Ray ray, MeshFace face, out Point3d result, out MeshHalfEdge halfEdge)
        {
            Vector3d faceNormal = MeshGeometry.FaceNormal(face);
            Vector3d biNormal   = Vector3d.CrossProduct(ray.Direction, faceNormal);

            Plane perpPlane = new Plane(ray.Origin, ray.Direction, faceNormal, biNormal);

            List <MeshVertex> vertices = face.AdjacentVertices();

            Point3d temp = new Point3d();

            Line line = new Line(vertices[0], vertices[1]);

            if (LinePlane(line, perpPlane, out temp) != ISLinePlane.Point)
            {
                result   = null;
                halfEdge = null;
                return(ISRayFacePerimeter.Point);
            } // No intersection found

            if (temp != ray.Origin && temp != null)
            {
                result   = temp;
                halfEdge = null;
                return(ISRayFacePerimeter.Point);
            } // Intersection found

            line = new Line(vertices[1], vertices[2]);
            if (LinePlane(line, perpPlane, out temp) != ISLinePlane.Point)
            {
                result   = null;
                halfEdge = null;
                return(ISRayFacePerimeter.NoIntersection);
            } // No intersection found

            if (temp != ray.Origin && temp != null)
            {
                result   = temp;
                halfEdge = null;
                return(ISRayFacePerimeter.Point);
            } // Intersection found

            line = new Line(vertices[2], vertices[0]);
            if (LinePlane(line, perpPlane, out temp) != ISLinePlane.Point)
            {
                result   = null;
                halfEdge = null;
                return(ISRayFacePerimeter.NoIntersection);
            }

            if (temp != ray.Origin && temp != null)
            {
                result   = temp;
                halfEdge = null;
                return(ISRayFacePerimeter.Point);
            }
            else
            {
                result   = null;
                halfEdge = null;
                return(ISRayFacePerimeter.Error);
            }
        }
Пример #30
0
        /// <summary>
        ///     Compute the intersection between a mesh face perimeter and a ray tangent to the face.
        /// </summary>
        /// <param name="ray">The tangent ray.</param>
        /// <param name="face">The mesh face.</param>
        /// <param name="result">The resulting intersection point.</param>
        /// <param name="halfEdge">The half-edge on where the intersection lies.</param>
        /// <returns>Intersection result.</returns>
        public static RayFacePerimeterIntersectionStatus RayFacePerimeter(
            Ray ray,
            MeshFace face,
            out Point3d result,
            out MeshHalfEdge halfEdge)
        {
            var faceNormal = MeshGeometry.FaceNormal(face);
            var biNormal   = Vector3d.CrossProduct(ray.Direction, faceNormal);

            var perpPlane = new Plane(ray.Origin, ray.Direction, faceNormal, biNormal);

            var vertices = face.AdjacentVertices();

            var temp = new Point3d();

            var line = new Line(vertices[0], vertices[1]);

            if (LinePlane(line, perpPlane, out temp) != LinePlaneIntersectionStatus.Point)
            {
                result   = null;
                halfEdge = null;
                return(RayFacePerimeterIntersectionStatus.Point);
            } // No intersection found

            if (temp != ray.Origin && temp != null)
            {
                result   = temp;
                halfEdge = null;
                return(RayFacePerimeterIntersectionStatus.Point);
            } // Intersection found

            line = new Line(vertices[1], vertices[2]);
            if (LinePlane(line, perpPlane, out temp) != LinePlaneIntersectionStatus.Point)
            {
                result   = null;
                halfEdge = null;
                return(RayFacePerimeterIntersectionStatus.NoIntersection);
            }

            if (temp != ray.Origin && temp != null)
            {
                result   = temp;
                halfEdge = null;
                return(RayFacePerimeterIntersectionStatus.Point);
            }

            line = new Line(vertices[2], vertices[0]);
            if (LinePlane(line, perpPlane, out temp) != LinePlaneIntersectionStatus.Point)
            {
                result   = null;
                halfEdge = null;
                return(RayFacePerimeterIntersectionStatus.NoIntersection);
            }

            if (temp != ray.Origin && temp != null)
            {
                result   = temp;
                halfEdge = null;
                return(RayFacePerimeterIntersectionStatus.Point);
            }

            result   = null;
            halfEdge = null;
            return(RayFacePerimeterIntersectionStatus.Error);
        }
        protected void BuildOneVertexBuffer( Matrix4 worldTransform,
                                             Matrix4 bindShapeMatrix,
                                             MeshGeometry geometry )
        {
            VertexData vertexData = geometry.VertexData;
            vertexData.vertexStart = 0;
            vertexData.vertexCount = geometry.IndexSets.Count;
            List<InputSource> geometryInputs = geometry.GetAllInputSources();

            #region Texture stuff

            // We need to build a compact set of texture coordinates.  There can be multiple
            // sets of texture coordinates, but the indices must start at 0 to work for all
            // graphics cards.
            Dictionary<InputSource, int> inputSetMap = new Dictionary<InputSource, int>();
            int maxInputSet = -1;
            Dictionary<int, List<InputSource>> unnumberedInputs = new Dictionary<int, List<InputSource>>();
            // First make a pass through, storing the index sets for the inputs
            for( int accessIndex = 0; accessIndex < geometryInputs.Count; ++accessIndex )
            {
                InputSource input = geometryInputs[ accessIndex ];
                if( input.Set != -1 )
                {
                    inputSetMap[ input ] = input.Set;
                    if( input.Set > maxInputSet )
                        maxInputSet = input.Set;
                }
                else
                    AddUnnumberedInput( input, unnumberedInputs );
            }
            // If we have stuff associated with input set 0, we need to find
            // out where to put the default data, such as position and normals.
            // We would like to assign input set 0 to these as well, but if
            // those are already used, we need to move whatever is there.
            if( unnumberedInputs.Count > 0 )
            {
                // We have some items that need a set. If there is no
                // collision with the inputs associated with 0, we can just
                // assign these entries to 0.  In that case, if there is no
                // collision with the lowest numbered set, we will also
                // want to move the lowest numbered set down to zero.
                List<int> keys = new List<int>( unnumberedInputs.Keys );

                keys.Sort();
                keys.Reverse();
                foreach( int i in keys )
                    AddUnnumberedInputs( unnumberedInputs[ i ], inputSetMap );
            }

            // Now build a mapping from input sets to texture indices
            // This collapses the set and removes gaps
            Dictionary<int, int> textureIndexMap = new Dictionary<int, int>();
            int maxTextureIndex = -1;
            List<int> inputIndices = new List<int>( inputSetMap.Values );
            inputIndices.Sort();
            foreach( int inputSetId in inputIndices )
            {
                if( textureIndexMap.ContainsKey( inputSetId ) )
                    continue;
                textureIndexMap[ inputSetId ] = ++maxTextureIndex;
            }

            #endregion Texture stuff

            // What is the offset into point components of the given input
            for( int accessIndex = 0; accessIndex < geometryInputs.Count; ++accessIndex )
            {
                InputSource input = geometryInputs[ accessIndex ];
                int textureIndex = textureIndexMap[ inputSetMap[ input ] ];
                m_Log.InfoFormat( "Assigned texture index {0} to input {1} with set {2}", textureIndex, input.Source, input.Set );
                ProcessInput( geometry, input, accessIndex, textureIndex, geometry.IndexSets.Count );
            }

            // If we are a pose target, we want to skip building the faces
            // and the submesh, and just skip to the next section where we
            // transform the geometry.
            if( !geometry.GeometrySet.IsPoseTarget )
            {
                foreach( SubMeshInfo smInfo in geometry.SubMeshes )
                {
                    // Ok, now use the geometry to make a submesh
                    IndexType indexType = IndexType.Size16;
                    if( geometry.IndexSets.Count > short.MaxValue )
                    {
                        indexType = IndexType.Size32;
                        m_Log.Warn( "Warning: submesh requires 32 bit index.  This will not work on DirectX 6 cards such as the common Intel series." );
                    }
                    ProcessFaces( smInfo, geometry, indexType );
                }
                if( geometry.SubMeshes.Count > 1 )
                {
                    if( m_AxiomMesh.SharedVertexData != null )
                    {
                        m_Log.Error( "Failed to load file: multiple shared submeshes" );
                        throw new Exception( "Failed to load file: multiple shared submeshes" );
                    }
                    m_AxiomMesh.SharedVertexData = vertexData;
                    foreach( SubMeshInfo smInfo in geometry.SubMeshes )
                    {
                        SubMesh subMesh = m_AxiomMesh.GetSubMesh( smInfo.name );
                        subMesh.useSharedVertices = true;
                    }
                }
                else if( geometry.SubMeshes.Count == 1 )
                {
                    string subMeshName = geometry.SubMeshes[ 0 ].name;
                    SubMesh subMesh = m_AxiomMesh.GetSubMesh( subMeshName );
                    subMesh.vertexData = vertexData;
                    subMesh.useSharedVertices = false;
                }
            }

            // Do the 'freeze transforms' step where we bake the transform
            // of this geometry into the data.  This is only the first part
            // of this.  We will also need to multiply it by the transform
            // matrix that was passed in via the command line.  Finally, we
            // generally need to transform this data to reskin it to the
            // skeleton's bind pose.
            // TODO: At some point, I could handle instanced geometry here by
            //       generating other submeshes.
            geometry.Transform( worldTransform * bindShapeMatrix );
        }
 public static void BuildBoundingBox( Mesh mesh, MeshGeometry geometry )
 {
     Vector3 max = mesh.BoundingBox.Maximum;
     Vector3 min = mesh.BoundingBox.Minimum;
     foreach( VertexDataEntry vde in geometry.VertexDataEntries )
     {
         if( vde.semantic != VertexElementSemantic.Position )
             continue;
         for( int i = 0; i < geometry.VertexData.vertexCount; ++i )
         {
             if( vde.fdata[ i, 0 ] < min.x )
                 min.x = vde.fdata[ i, 0 ];
             if( vde.fdata[ i, 0 ] > max.x )
                 max.x = vde.fdata[ i, 0 ];
             if( vde.fdata[ i, 1 ] < min.y )
                 min.y = vde.fdata[ i, 1 ];
             if( vde.fdata[ i, 1 ] > max.y )
                 max.y = vde.fdata[ i, 1 ];
             if( vde.fdata[ i, 2 ] < min.z )
                 min.z = vde.fdata[ i, 2 ];
             if( vde.fdata[ i, 2 ] > max.z )
                 max.z = vde.fdata[ i, 2 ];
         }
     }
     mesh.BoundingBox = new AxisAlignedBox( min, max );
 }
Пример #33
0
        private void CanCompute_MeshArea()
        {
            var area = MeshGeometry.TotalArea(this.FlatTriangle);

            Assert.True(Math.Abs(area - 0.5) < Settings.Tolerance);
        }
Пример #34
0
 public ModelMesh(MeshGeometry geometry)
 {
     Geometry = geometry;
     UpdateMeshProperties();
 }
Пример #35
0
        private int ConvertMeshMultiMaterial(MeshGeometry mesh, Model model, int index, Matrix nodeGlobalTransform)
        {
            var outMesh = SetupEmptyMesh(mesh);
            var mindices = mesh.MaterialIndices;
            var vertices = mesh.Vertices;
            var faces = mesh.FaceIndexCounts;
            var processWeights = Doc.Settings.ReadWeights && (mesh.DeformerSkin != null);

            int countFaces = 0;
            int countVertices = 0;

            // count faces
            var itf = faces.GetEnumerator();
            foreach(var it in mindices)
            {
                itf.MoveNext();
                if (it != index)
                {
                    continue;
                }
                ++countFaces;
                countVertices += (int)itf.Current;
            }

            Debug.Assert(countFaces > 0);
            Debug.Assert(countVertices > 0);

            // mapping from output indices to DOM indexing, needed to resolve weights
            var reverseMappigng = new int[0];
            if (processWeights)
            {
                reverseMappigng = new int[countVertices];
            }

            // allocate output data arrays, but don't fill them yet
            outMesh.Vertices = new Vector3[countVertices];
            var fac = outMesh.Faces = new AssimpSharp.Face[countFaces];

            // allocate normals
            var normals = mesh.Normals;
            if (normals.Count > 0)
            {
                Debug.Assert(normals.Count == vertices.Count);
                outMesh.Normals = new Vector3[vertices.Count];
            }

            // allocate tangents, binormals.
            var tangets = mesh.Tangents;
            var binormals = mesh.Binormals;
            if (tangets.Count > 0)
            {
                Vector3[] tempBinormals = new Vector3[0];
                if (binormals.Count == 0)
                {
                    if (normals.Count > 0)
                    {
                        // XXX this computes the binormals for the entire mesh, not only
                        // the part for which we need them.
                        tempBinormals = new Vector3[normals.Count];
                        for (int i = 0; i < tangets.Count; i++)
                        {
                            tempBinormals[i] = Vector3.Cross(normals[i], tangets[i]);
                        }
                        binormals.Clear();
                        for (int i = 0; i < tempBinormals.Length; i++)
                        {
                            binormals.Add(tempBinormals[i]);
                        }
                    }
                    else
                    {
                        binormals = null;
                    }
                }

                if (binormals.Count > 0)
                {
                    Debug.Assert(tangets.Count == vertices.Count);
                    Debug.Assert(binormals.Count == vertices.Count);

                    outMesh.Tangents = new Vector3[vertices.Count];
                    outMesh.Bitangents = new Vector3[vertices.Count];
                }
            }

            // allocate texture coords
            int numUvs = 0;
            for (int i = 0; i < AssimpSharp.Mesh.AI_MAX_NUMBER_OF_TEXTURECOORDS; i++, numUvs++)
            {
                var uvs = mesh.GetTextureCoords(i);
                if (uvs.Count == 0)
                {
                    break;
                }
                outMesh.TextureCoords[i] = new Vector3[vertices.Count];
                outMesh.NumUVComponents[i] = 2;
            }

            // allocate vertex colors
            int numVcs = 0;
            for (int i = 0; i < AssimpSharp.Mesh.AI_MAX_NUMBER_OF_COLOR_SETS; i++, numVcs++)
            {
                var colors = mesh.GetVertexColors(i);
                if (colors.Count == 0)
                {
                    break;
                }
                outMesh.Colors[i] = new Color4[vertices.Count];
            }

            int cursor = 0;
            int inCursor = 0;

            int facesIndex = 0;
            int facIndex = 0;
            foreach (var it in mindices)
            {
                int pcount = (int)faces[facesIndex];
                if (it != index)
                {
                    inCursor += pcount;
                    continue;
                }

                var f = fac[facIndex++] = new Face();
                f.Indices = new int[pcount];
                switch (pcount)
                {
                    case 1:
                        outMesh.PrimitiveTypes |= AssimpSharp.PrimitiveType.Point;
                        break;
                    case 2:
                        outMesh.PrimitiveTypes |= AssimpSharp.PrimitiveType.Line;
                        break;
                    case 3:
                        outMesh.PrimitiveTypes |= AssimpSharp.PrimitiveType.Triangle;
                        break;
                    default:
                        outMesh.PrimitiveTypes |= AssimpSharp.PrimitiveType.Polygon;
                        break;
                }
                for (int i = 0; i < pcount; ++i, ++cursor, ++inCursor)
                {
                    f.Indices[i] = cursor;
                    if (reverseMappigng.Length > 0)
                    {
                        reverseMappigng[cursor] = inCursor;
                    }
                    outMesh.Vertices[cursor] = vertices[inCursor];
                    if (outMesh.Normals.Length > 0)
                    {
                        outMesh.Normals[cursor] = normals[inCursor];
                    }
                    if (outMesh.Tangents.Length > 0)
                    {
                        outMesh.Tangents[cursor] = tangets[inCursor];
                        outMesh.Bitangents[cursor] = binormals[inCursor];
                    }
                    for (int j = 0; j < numUvs; j++)
                    {
                        var uvs = mesh.GetTextureCoords(j);
                        outMesh.TextureCoords[j][cursor] = new Vector3(uvs[inCursor], 0.0f);
                    }
                    for (int j = 0; j < numVcs; j++)
                    {
                        var cols = mesh.GetVertexColors(j);
                        outMesh.Colors[j][cursor] = cols[inCursor];
                    }
                }
            }

            ConvertMaterialForMesh(outMesh, model, mesh, index);

            if (processWeights)
            {
                ConvertWeights(outMesh, model, mesh, nodeGlobalTransform, index, reverseMappigng);
            }
            return Meshes.Count - 1;
        }
Пример #36
0
 private void SetTextureProperties(aiMaterial outMat, Dictionary<string, LayeredTexture> layeredTextures, MeshGeometry mesh)
 {
     TrySetTextureProperties(outMat, layeredTextures, "DiffuseColor", aiTextureType.Diffuse, mesh);
     TrySetTextureProperties(outMat, layeredTextures, "AmbientColor", aiTextureType.Ambient, mesh);
     TrySetTextureProperties(outMat, layeredTextures, "EmissiveColor", aiTextureType.Emissive, mesh);
     TrySetTextureProperties(outMat, layeredTextures, "SpecularColor", aiTextureType.Specular, mesh);
     TrySetTextureProperties(outMat, layeredTextures, "TransparentColor", aiTextureType.Opacity, mesh);
     TrySetTextureProperties(outMat, layeredTextures, "ReflectionColor", aiTextureType.Reflection, mesh);
     TrySetTextureProperties(outMat, layeredTextures, "DisplacementColor", aiTextureType.Displacement, mesh);
     TrySetTextureProperties(outMat, layeredTextures, "NormalMap", aiTextureType.Normals, mesh);
     TrySetTextureProperties(outMat, layeredTextures, "Bump", aiTextureType.Height, mesh);
     TrySetTextureProperties(outMat, layeredTextures, "ShininessExponent", aiTextureType.Shininess, mesh);
 }
Пример #37
0
 public MeshFile(MeshGeometry geometry)
 {
     Geometry = geometry;
     Type     = geometry.GetMeshType();
     Cullings = new List <MeshCulling>();
 }
 public virtual void ReadPolygon( MeshGeometry geometry, bool doubleSided, XmlNode node )
 {
     string[] indices = node.InnerText.Split( (char[]) null, StringSplitOptions.RemoveEmptyEntries );
     int inputCount = geometry.InputCount;
     // How many vertices are in this polygon
     int vertexCount = indices.Length / inputCount;
     // Indices (into currentPoint) of the points in a polygon.
     // This is temporary, and is reset for each polygon
     List<int> cwPolyPoints = geometry.BeginPolygon();
     List<int> ccwPolyPoints = geometry.BeginPolygon();
     for( int vertex = 0; vertex < vertexCount; ++vertex )
     {
         PointComponents currentPoint = geometry.BeginPoint();
         foreach( int inputIndex in geometry.InputSources.Keys )
         {
             List<InputSourceCollection> inputs = geometry.InputSources[ inputIndex ];
             int ptIndex = int.Parse( indices[ vertex * inputCount + inputIndex ] );
             foreach( InputSourceCollection isc in inputs )
             {
                 foreach( InputSource source in isc.GetSources() )
                     geometry.AddPointComponent( currentPoint, ptIndex );
                 // Set the vertex index of this point.  This is used by
                 // combiners, which reference vertices by their position
                 // in the vertex array.
                 if( isc is VertexInputSource )
                     currentPoint.VertexIndex = ptIndex;
             }
         }
         geometry.EndPoint( currentPoint, cwPolyPoints, ccwPolyPoints );
     }
     geometry.EndPolygon( cwPolyPoints );
     if( doubleSided )
     {
         ccwPolyPoints.Reverse();
         geometry.EndPolygon( ccwPolyPoints );
     }
 }
Пример #39
0
        private int[] ConvertMesh(MeshGeometry mesh, Model model,
            Matrix nodeGlobalTransform)
        {
            List<int> temp;
            if (MeshesConverted.TryGetValue(mesh, out temp))
            {
                return temp.ToArray();
            }
            else
            {
                temp = new List<int>();
            }

            var vertices = mesh.Vertices;
            var faces = mesh.FaceIndexCounts;
            if (vertices.Count == 0 || faces.Count == 0)
            {
                Debug.WriteLine("ignore empty geometry: " + mesh.Name);
                return temp.ToArray();
            }

            var mindices = mesh.MaterialIndices;
            if (Doc.Settings.ReadMaterials && !(mindices.Count == 0))
            {
                var b = mindices[0];
                foreach (var index in mindices)
                {
                    if (index != b)
                    {
                        return ConvertMeshMultiMaterial(mesh, model, nodeGlobalTransform).ToArray();
                    }
                }
            }

            temp.Add(ConvertMeshSingleMaterial(mesh, model, nodeGlobalTransform));
            return temp.ToArray();
        }
        /// <summary>
        ///   ReadPolygons basically corresponds to reading in a SubMesh.
        ///   The grandparent of this node is probably the geometry node
        ///   with the submesh name.
        /// </summary>
        /// <param name="node">The node corresponding to the 'polygons' element</param>
        public void ReadPolygons( MeshGeometry geometry,
                                    Dictionary<string, VertexSet> vertexSets,
                                    XmlNode node, ColladaMeshInfo meshInfo )
        {
            bool doubleSided = false;

            Dictionary<int, List<InputSourceCollection>> inputSources =
                new Dictionary<int, List<InputSourceCollection>>();
            // First pass to get params and inputs
            foreach( XmlNode childNode in node.ChildNodes )
            {
                switch( childNode.Name )
                {
                case "param":
                    if( childNode.Attributes[ "name" ].Value == "DOUBLE_SIDED" )
                        doubleSided = bool.Parse( childNode.InnerText );
                    break;
                case "input":
                    ReadInput( inputSources, vertexSets, childNode, meshInfo );
                    break;
                case "p":
                    // ignore on this pass
                    break;
                default:
                    DebugMessage( childNode );
                    break;
                }
            }
            foreach( int inputIndex in inputSources.Keys )
                geometry.AddInputs( inputIndex, inputSources[ inputIndex ] );

            // TODO: If we are double sided, we probably need to build a
            // negated version of the normals.

            // second pass to handle the 'p' entries
            foreach( XmlNode childNode in node.ChildNodes )
            {
                switch( childNode.Name )
                {
                case "param":
                case "input":
                    // ignore on this pass
                    break;
                case "p":
                    ReadPolygon( geometry, doubleSided, childNode );
                    break;
                default:
                    DebugMessage( childNode );
                    break;
                }
            }
            string materialId = null;
            string submeshName = geometry.Id;
            if( node.Attributes[ "material" ] != null &&
                node.Attributes[ "material" ].Value != null )
            {
                materialId = node.Attributes[ "material" ].Value;
                // strip off the leading '#'
                if( materialId.StartsWith( "#" ) )
                {
                    log.InfoFormat( "Material {0} starts with '#'", materialId );
                    materialId = materialId.Substring( 1 );
                }
                // I used to append the material name to the submesh name,
                // but now I want to leave it alone.
                //submeshName = submeshName + "/" + materialId;
            }
            SubMeshInfo smInfo = new SubMeshInfo();
            smInfo.name = submeshName;
            if( materialId != null )
            {
                if( MaterialScriptBuilder.MaterialNamespace != null )
                    smInfo.material = MaterialScriptBuilder.MaterialNamespace + "." + materialId;
                else
                    smInfo.material = materialId;
            }
            else
            {
                smInfo.material = "BaseWhite";
            }
            geometry.AddSubMesh( smInfo );
        }
Пример #41
0
        private void ConvertMaterialForMesh(aiMesh result, Model model, MeshGeometry geo, int materialIndex)
        {
            // locate source materials for this mesh
            var mats = model.Materials;
            if (materialIndex >= mats.Count || materialIndex < 0)
            {
                FBXImporter.LogError("material index out of bounds, setting default material");
                result.MaterialIndex = GetDefaultMaterial();
                return;
            }

            var mat = mats[materialIndex];
            int it;
            if (MaterialsConverted.TryGetValue(mat, out it))
            {
                result.MaterialIndex = it;
                return;
            }

            result.MaterialIndex = ConvertMaterial(mat, geo);
            this.MaterialsConverted[mat] = result.MaterialIndex;
        }
        public virtual void ReadMesh( string geometryName, XmlNode node, ColladaMeshInfo meshInfo )
        {
            Dictionary<int, List<InputSourceCollection>> inputSources =
                new Dictionary<int, List<InputSourceCollection>>();
            Dictionary<string, VertexSet> vertexSets = new Dictionary<string, VertexSet>();

            foreach( XmlNode childNode in node.ChildNodes )
            {
                switch( childNode.Name )
                {
                case "source":
                    ReadSource( null, childNode, meshInfo );
                    break;
                case "vertices":
                    // Read in inputs and vertex sets that should apply to all
                    // the sub-portions of this geometry.
                    ReadVertices( vertexSets, childNode, meshInfo );
                    break;
                case "lines":
                case "linestrips":
                case "triangles":
                case "trifans":
                case "tristrips":
                case "polygons":
                    // Handle this in the second pass
                    break;
                default:
                    DebugMessage( childNode );
                    break;
                }
            }

            int submeshIndex = 0;
            foreach( XmlNode childNode in node.ChildNodes )
            {
                switch( childNode.Name )
                {
                case "source":
                case "vertices":
                    // these were handled in the first pass
                    break;
                case "polygons":
                case "triangles":
                    {
                        string name = string.Format( "{0}.{1}", geometryName, submeshIndex++ );
                        if( !meshInfo.Geometries.ContainsKey( geometryName ) )
                            meshInfo.Geometries[ geometryName ] = new GeometrySet( geometryName );
                        GeometrySet geoSet = meshInfo.Geometries[ geometryName ];
                        MeshGeometry geometry = new MeshGeometry( name, geoSet );
                        foreach( VertexSet vertexSet in vertexSets.Values )
                            geometry.AddVertexSet( vertexSet );
                        foreach( int inputIndex in inputSources.Keys )
                            geometry.AddInputs( inputIndex, inputSources[ inputIndex ] );
                        geoSet.Add( geometry );
                        ReadPolygons( geometry, vertexSets, childNode, meshInfo );
                        break;
                    }
                case "lines":
                case "linestrips":
                case "trifans":
                case "tristrips":
                default:
                    DebugMessage( childNode );
                    break;
                }
            }
        }
Пример #43
0
        public BasicModel(Device device, TextureManager texMgr, string filename, string texturePath)
        {
            _subsets = new List<MeshGeometry.Subset>();
            _vertices = new List<PosNormalTexTan>();
            _indices = new List<short>();
            DiffuseMapSRV = new List<ShaderResourceView>();
            NormalMapSRV = new List<ShaderResourceView>();
            Materials = new List<Material>();
            _modelMesh = new MeshGeometry();

            var importer = new AssimpImporter();
            if (!importer.IsImportFormatSupported(Path.GetExtension(filename))) {
                throw new ArgumentException("Model format " + Path.GetExtension(filename) + " is not supported!  Cannot load {1}", "filename");
            }
            #if DEBUG

            importer.AttachLogStream(new ConsoleLogStream());
            importer.VerboseLoggingEnabled = true;
            #endif
            var model = importer.ImportFile(filename, PostProcessSteps.GenerateSmoothNormals | PostProcessSteps.CalculateTangentSpace);

            var min = new Vector3(float.MaxValue);
            var max = new Vector3(float.MinValue);
            var verts = new List<PosNormalTexTan>();
            foreach (var mesh in model.Meshes) {
                var subset = new MeshGeometry.Subset {

                    VertexCount = mesh.VertexCount,
                    VertexStart = _vertices.Count,
                    FaceStart = _indices.Count / 3,
                    FaceCount = mesh.FaceCount
                };
                _subsets.Add(subset);
                // bounding box corners

                for (var i = 0; i < mesh.VertexCount; i++) {
                    var pos = mesh.HasVertices ? mesh.Vertices[i].ToVector3() : new Vector3();
                    min = Vector3.Minimize(min, pos);
                    max = Vector3.Maximize(max, pos);

                    var norm = mesh.HasNormals ? mesh.Normals[i] : new Vector3D();
                    var texC = mesh.HasTextureCoords(0) ? mesh.GetTextureCoords(0)[i] : new Vector3D();
                    var tan = mesh.HasTangentBasis ? mesh.Tangents[i] : new Vector3D();
                    var v = new PosNormalTexTan(pos, norm.ToVector3(), texC.ToVector2(), tan.ToVector3());
                    verts.Add(v);
                }

                _vertices.AddRange(verts);

                var indices = mesh.GetIndices().Select(i => (short)(i + (uint)subset.VertexStart)).ToList();
                _indices.AddRange(indices);

                var mat = model.Materials[mesh.MaterialIndex];
                var material = mat.ToMaterial();

                Materials.Add(material);

                var diffusePath = mat.GetTexture(TextureType.Diffuse, 0).FilePath;
                if (Path.GetExtension(diffusePath) == ".tga") {
                    // DirectX doesn't like to load tgas, so you will need to convert them to pngs yourself with an image editor
                    diffusePath = diffusePath.Replace(".tga", ".png");
                }
                if (!string.IsNullOrEmpty(diffusePath)) {
                    DiffuseMapSRV.Add(texMgr.CreateTexture(Path.Combine(texturePath, diffusePath)));
                }
                var normalPath = mat.GetTexture(TextureType.Normals, 0).FilePath;
                if (!string.IsNullOrEmpty(normalPath)) {
                    NormalMapSRV.Add(texMgr.CreateTexture(Path.Combine(texturePath, normalPath)));
                } else {
                    var normalExt = Path.GetExtension(diffusePath);
                    normalPath = Path.GetFileNameWithoutExtension(diffusePath) + "_nmap" + normalExt;

                    NormalMapSRV.Add(texMgr.CreateTexture(Path.Combine(texturePath, normalPath)));

                }
            }
            BoundingBox = new BoundingBox(min, max);
            _modelMesh.SetSubsetTable(_subsets);
            _modelMesh.SetVertices(device, _vertices);
            _modelMesh.SetIndices(device, _indices);
        }
Пример #44
0
 private BasicModel()
 {
     _subsets = new List<MeshGeometry.Subset>();
     _vertices = new List<PosNormalTexTan>();
     _indices = new List<short>();
     DiffuseMapSRV = new List<ShaderResourceView>();
     NormalMapSRV = new List<ShaderResourceView>();
     Materials = new List<Material>();
     _modelMesh = new MeshGeometry();
 }
Пример #45
0
        private aiMesh SetupEmptyMesh(MeshGeometry mesh)
        {
            var outMesh = new aiMesh();
            this.Meshes.Add(outMesh);
            if (MeshesConverted.ContainsKey(mesh))
            {
                this.MeshesConverted[mesh].Add(this.Meshes.Count - 1);
            }
            else
            {
                this.MeshesConverted[mesh] = new List<int>() {this.Meshes.Count - 1 };
            }

            // set name
            var name = mesh.Name;
            if (name.StartsWith("Geometry::"))
            {
                name = name.Substring(10);
            }

            if (!string.IsNullOrEmpty(name))
            {
                outMesh.Name = name;
            }

            return outMesh;
        }
Пример #46
0
        private void CanCompute_FaceNormal()
        {
            var normal = MeshGeometry.FaceNormal(this.FlatTriangle.Faces[0]);

            Assert.Equal(Vector3d.UnitZ, normal);
        }
Пример #47
0
        public SkinnedModel(Device device, TextureManager texMgr, string filename, string texturePath, bool flipTexY = false)
        {
            // initialize collections
            _subsets = new List<MeshGeometry.Subset>();
            _vertices = new List<PosNormalTexTanSkinned>();
            _indices = new List<short>();
            DiffuseMapSRV = new List<ShaderResourceView>();
            NormalMapSRV = new List<ShaderResourceView>();
            Materials = new List<Material>();

            var importer = new AssimpImporter();
            #if DEBUG
            importer.AttachLogStream(new ConsoleLogStream());
            importer.VerboseLoggingEnabled = true;
            #endif
            var model = importer.ImportFile(filename, PostProcessSteps.GenerateSmoothNormals | PostProcessSteps.CalculateTangentSpace );

            // Load animation data
            Animator = new SceneAnimator();
            Animator.Init(model);

            // create our vertex-to-boneweights lookup
            var vertToBoneWeight = new Dictionary<uint, List<VertexWeight>>();
            // create bounding box extents
            _min = new Vector3(float.MaxValue);
            _max = new Vector3(float.MinValue);

            foreach (var mesh in model.Meshes) {
                ExtractBoneWeightsFromMesh(mesh, vertToBoneWeight);
                var subset = new MeshGeometry.Subset {
                    VertexCount = mesh.VertexCount,
                    VertexStart = _vertices.Count,
                    FaceStart = _indices.Count / 3,
                    FaceCount = mesh.FaceCount
                };
                _subsets.Add(subset);

                var verts = ExtractVertices(mesh, vertToBoneWeight, flipTexY);
                _vertices.AddRange(verts);
                // extract indices and shift them to the proper offset into the combined vertex buffer
                var indices = mesh.GetIndices().Select(i => (short)(i + (uint)subset.VertexStart)).ToList();
                _indices.AddRange(indices);

                // extract materials
                var mat = model.Materials[mesh.MaterialIndex];
                var material = mat.ToMaterial();
                Materials.Add(material);

                // extract material textures
                var diffusePath = mat.GetTexture(TextureType.Diffuse, 0).FilePath;
                if (!string.IsNullOrEmpty(diffusePath)) {
                    DiffuseMapSRV.Add(texMgr.CreateTexture(Path.Combine(texturePath, diffusePath)));
                }
                var normalPath = mat.GetTexture(TextureType.Normals, 0).FilePath;
                if (!string.IsNullOrEmpty(normalPath)) {
                    NormalMapSRV.Add(texMgr.CreateTexture(Path.Combine(texturePath, normalPath)));
                } else {
                    // for models created without a normal map baked, we'll check for a texture with the same
                    // filename as the diffure texture, and _nmap suffixed
                    // this lets us add our own normal maps easily
                    var normalExt = Path.GetExtension(diffusePath);
                    normalPath = Path.GetFileNameWithoutExtension(diffusePath) + "_nmap" + normalExt;
                    if (File.Exists(Path.Combine(texturePath, normalPath))) {
                        NormalMapSRV.Add(texMgr.CreateTexture(Path.Combine(texturePath, normalPath)));
                    }
                }
            }
            BoundingBox = new BoundingBox(_min, _max);
            _modelMesh = new MeshGeometry();
            _modelMesh.SetSubsetTable(_subsets);
            _modelMesh.SetVertices(device, _vertices);
            _modelMesh.SetIndices(device, _indices);
        }
 /// <summary>
 ///   Take the data from input, and use it to build a two dimensional 
 ///   array of data which will be added to the geometry's 
 ///   VertexDataElements.
 /// </summary>
 /// <param name="geometry">the mesh geometry that owns the data</param>
 /// <param name="input">the input source with the information to populate the vertex data</param>
 /// <param name="accessIndex">the index where our data is in the source</param>
 /// <param name="textureIndex">the texture index when appropriate or 0</param>
 /// <param name="vertexCount">the number of vertices</param>
 protected void ProcessInput( MeshGeometry geometry,
                             InputSource input,
                             int accessIndex,
                             int textureIndex,
                             int vertexCount )
 {
     VertexDataEntry vde = null;
     switch( input.Semantic )
     {
     case "POSITION":
     case "BIND_SHAPE_POSITION":
         vde = HWBuffer.ExtractData(
                           VertexElementSemantic.Position,
                           vertexCount, input,
                           geometry.IndexSets, accessIndex );
         break;
     case "NORMAL":
     case "BIND_SHAPE_NORMAL":
         vde = HWBuffer.ExtractData(
                           VertexElementSemantic.Normal,
                           vertexCount, input,
                           geometry.IndexSets, accessIndex );
         break;
     case "COLOR":
         vde = HWBuffer.ExtractData(
                           VertexElementSemantic.Diffuse,
                           vertexCount, input,
                           geometry.IndexSets, accessIndex );
         break;
     case "UV":
     case "TEXCOORD":
         vde = HWBuffer.ExtractData(
                           VertexElementSemantic.TexCoords,
                           vertexCount, input,
                           geometry.IndexSets, accessIndex );
         break;
     case "TANGENT":
     case "TEXTANGENT":
         vde = HWBuffer.ExtractData(
                           VertexElementSemantic.Tangent,
                           vertexCount, input,
                           geometry.IndexSets, accessIndex );
         break;
     case "BINORMAL":
     case "TEXBINORMAL":
         vde = HWBuffer.ExtractData(
                           VertexElementSemantic.Binormal,
                           vertexCount, input,
                           geometry.IndexSets, accessIndex );
         break;
     default:
         m_Log.WarnFormat( "Not yet handling input semantic: {0}", input.Semantic );
         break;
     }
     if( vde != null )
     {
         vde.textureIndex = textureIndex;
         geometry.VertexDataEntries.Add( vde );
     }
 }
Пример #49
0
        public static MeshFile ReadMesh(Stream stream)
        {
            try
            {
                var  meshFile   = ReadMeshFile(stream);
                var  meshType   = (MeshType)meshFile.Header.MeshType;
                bool isTextured = meshType == MeshType.StandardTextured || meshType == MeshType.FlexibleTextured;
                bool isFlexible = meshType == MeshType.Flexible || meshType == MeshType.FlexibleTextured;

                var mainMesh = MeshGeometry.Create(meshFile.Geometry);

                SetShaderData(meshFile, meshFile.Geometry, mainMesh);

                var mesh = new MeshFile(mainMesh);
                if (stream is FileStream fs)
                {
                    mesh.Filename = fs.Name;
                }

                mesh.SetGeometry(mainMesh);

                for (int i = 0; i < meshFile.Cullings.Length; i++)
                {
                    var data    = meshFile.Cullings[i];
                    var culling = new MeshCulling((MeshCullingType)data.Type)
                    {
                        FromIndex   = data.FromIndex,
                        IndexCount  = data.IndexCount,
                        FromVertex  = data.FromVertex,
                        VertexCount = data.VertexCount,
                    };

                    if (data.Studs != null && data.Studs.Length > 0)
                    {
                        for (int j = 0; j < data.Studs.Length; j++)
                        {
                            culling.Studs.Add(new Custom2DFieldReference(data.Studs[j]));
                        }
                    }

                    if (data.AdjacentStuds != null && data.AdjacentStuds.Length > 0)
                    {
                        for (int j = 0; j < data.AdjacentStuds.Length; j++)
                        {
                            culling.AdjacentStuds.Add(new Custom2DFieldReference(data.AdjacentStuds[j]));
                        }
                    }

                    if (data.AlternateMesh.HasValue)
                    {
                        var geom = MeshGeometry.Create(data.AlternateMesh.Value);
                        SetShaderData(meshFile, data.AlternateMesh.Value, geom);
                        culling.ReplacementMesh = geom;
                    }

                    mesh.Cullings.Add(culling);
                }
                return(mesh);
            }
            catch
            {
                throw;
            }
        }
Пример #50
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            // --- variables ---

            MeshGeometry  mesh     = new MeshGeometry();
            List <string> bctxt    = new List <string>();
            List <string> loadtxt  = new List <string>();
            List <string> deftxt   = new List <string>();
            Material      material = new Material();
            Boolean       opt      = false;


            // --- input ---

            if (!DA.GetData(0, ref mesh))
            {
                return;
            }
            if (!DA.GetDataList(1, bctxt))
            {
                return;
            }
            if (!DA.GetDataList(2, loadtxt))
            {
                return;
            }
            if (!DA.GetDataList(3, deftxt))
            {
                return;
            }
            if (!DA.GetData(4, ref material))
            {
                return;
            }

            // --- setup ---

            List <List <int> > connectivity = mesh.GetConnectivity();
            List <Point3d>     globalPoints = mesh.GetGlobalPoints();
            List <Node>        nodes        = mesh.GetNodeList();
            BrepGeometry       brp          = mesh.GetBrep();
            Brep origBrep = brp.GetBrep();

            int    sizeOfMatrix      = mesh.GetSizeOfMatrix();
            int    removableElements = FindRemovableElements(nodes, mesh.GetElements());
            int    totalElements     = mesh.GetElements().Count;
            int    numberElements    = mesh.GetElements().Count;
            double removableVolume   = mesh.GetOptVolume();
            double minElements       = totalElements - Math.Floor(totalElements * removableVolume / 100);

            // --- solve ---

            if (removableVolume != 0)
            {
                opt = true;
            }

            Boolean           first        = true;
            double            max          = 0;
            int               removeElem   = -1;
            List <int>        removeNodeNr = new List <int>();
            DataTree <double> defTree      = new DataTree <double>();

            while (numberElements > minElements && max < material.GetY() || first) //Requirements for removal
            {
                first = false;

                for (int i = 0; i < nodes.Count; i++)
                {
                    nodes[i].CleanStress();
                }

                List <Element> elements = mesh.GetElements();

                //Remove selected element from last iterations, and update afftected nodes
                if (removeElem != -1 && opt == true)
                {
                    RemoveElementAndUpdateNodes(elements, removeElem, removeNodeNr);
                }

                //Create Ktot and B
                Matrix <double> Ktot = CreateGlobalStiffnessMatrix(sizeOfMatrix, material, elements);

                //Create boundary condition list AND predeformations
                (List <int> bcNodes, List <double> reatrains) = CreateBCList(bctxt, globalPoints);

                (List <int> predefNodes, List <double> predef) = CreateBCList(deftxt, globalPoints);

                //Setter 0 i hver rad med bc og predef, og diagonal til 1.
                Ktot = ApplyBCrow(Ktot, bcNodes);
                Ktot = ApplyBCrow(Ktot, predefNodes);

                //Needs to take the predefs into account
                Vector <double> Rdef = Vector <double> .Build.Dense(sizeOfMatrix);

                if (deftxt.Any())
                {
                    Rdef = ApplyPreDef(Ktot, predefNodes, predef, sizeOfMatrix);
                }

                //double[] R_array = SetLoads(sizeOfM, loadtxt);
                double[] Rload = AssignLoadsDefAndBC(loadtxt, predefNodes, predef, bcNodes, globalPoints);

                //Adding R-matrix for pre-deformations.
                var             V = Vector <double> .Build;
                Vector <double> R = (V.DenseOfArray(Rload)).Subtract(Rdef);

                //Apply boundary condition and predeformations (Puts 0 in columns of K)
                Ktot = ApplyBCcol(Ktot, bcNodes);
                Ktot = ApplyBCcol(Ktot, predefNodes);

                //Removing row and column in K and R, and nodes with removeNodeNr
                if (opt == true)
                {
                    List <Node> nodes_removed = mesh.GetNodeList().ConvertAll(x => x);
                    (Ktot, R, nodes) = UpdateKandR(removeNodeNr, Ktot, R, nodes_removed);
                }

                //Inverting K matrix. Singular when all elements belonging to a node is removed
                Matrix <double> KtotInverse = Ktot.Inverse();

                //Caluculation of the displacement vector u
                Vector <double> u = KtotInverse.Multiply(R);

                //Creating tree for output of deformation. Structured in x,y,z for each node. As well as asigning deformation to each node class
                defTree = DefToTree(u, nodes);

                //Calculatin strains for each node in elements
                CalcStrainAndStress(elements, material);

                //Calculate global stresses from strain
                CalcStrainAndStressGlobal(nodes, material);
                SetAverageStresses(elements);

                //Find element to be removed next
                if (opt == true)
                {
                    (max, removeElem) = mesh.RemoveOneElement();
                    numberElements    = mesh.GetElements().Count;
                }
            }
            DataTree <double> strainTree = new DataTree <double>();
            DataTree <double> stressTree = new DataTree <double>();

            for (int i = 0; i < nodes.Count; i++)
            {
                strainTree.AddRange(nodes[i].GetGlobalStrain(), new GH_Path(new int[] { 0, i }));
                stressTree.AddRange(nodes[i].GetGlobalStress(), new GH_Path(new int[] { 0, i }));
            }

            //FOR PREVIEW OF HEADLINE

            //Setting up reference values
            (double refLength, Point3d centroid) = GetRefValues(origBrep);

            //Creating text-information for showing in VR
            (string headText, double headSize, Plane headPlane, Color headColor) = CreateHeadline(centroid, refLength);

            //---output---

            DA.SetDataTree(0, defTree);
            DA.SetDataTree(1, strainTree);
            DA.SetDataTree(2, stressTree);
            DA.SetData(3, headText);
            DA.SetData(4, headSize);
            DA.SetData(5, headPlane);
            DA.SetData(6, headColor);
        }
        public override void ReadMesh( string geometryName, XmlNode node, ColladaMeshInfo meshInfo )
        {
            Dictionary<int, List<InputSourceCollection>> inputSources =
                new Dictionary<int, List<InputSourceCollection>>();
            Dictionary<string, VertexSet> vertexSets = new Dictionary<string, VertexSet>();
            int submeshIndex = 0;

            foreach( XmlNode childNode in node.ChildNodes )
            {
                switch( childNode.Name )
                {
                case "source":
                    ReadSource( null, childNode, meshInfo );
                    break;
                case "vertices":
                    // Read in inputs and vertex sets that should apply to all
                    // the sub-portions of this geometry.
                    ReadVertices( vertexSets, childNode, meshInfo );
                    break;
                case "polygons":
                case "polylist":
                case "triangles":
                    {
                        string name = string.Format( "{0}.{1}", geometryName, submeshIndex++ );
                        if( !meshInfo.Geometries.ContainsKey( geometryName ) )
                            meshInfo.Geometries[ geometryName ] = new GeometrySet( geometryName );
                        GeometrySet geoSet = meshInfo.Geometries[ geometryName ];
                        MeshGeometry geometry = new MeshGeometry( name, geoSet );
                        foreach( VertexSet vertexSet in vertexSets.Values )
                            geometry.AddVertexSet( vertexSet );
                        geoSet.Add( geometry );
                        if( childNode.Name == "triangles" )
                            ReadTriangles( geometry, vertexSets, childNode, meshInfo );
                        else if( childNode.Name == "polygons" )
                            ReadPolygons( geometry, vertexSets, childNode, meshInfo );
                        else if( childNode.Name == "polylist" )
                            log.Error( "TODO: Add support for polylist" );
                        break;
                    }
                case "lines":
                case "linestrips":
                case "trifans":
                case "tristrips":
                default:
                    DebugMessage( childNode );
                    break;
                }
            }
        }
Пример #52
0
        private void ConvertWeights(aiMesh result, Model model, MeshGeometry geo, Matrix nodeGlobalTransform, int materialIndex = FbxConverter.NO_MATERIAL_SEPARATION, int[] outputVertStartIndices = null)
        {
            Debug.Assert(geo.DeformerSkin != null);
            var outIndices = new List<int>();
            var indexOutIndices = new List<int>();
            var countOutIndices = new List<int>();

            var sk = geo.DeformerSkin;

            var bones = new List<aiBone>(sk.Clusters.Count);

            var noMatCheck = (materialIndex == FbxConverter.NO_MATERIAL_SEPARATION);
            Debug.Assert(noMatCheck || outputVertStartIndices != null);

            try
            {
                foreach (var cluster in sk.Clusters)
                {
                    Debug.Assert(cluster != null);

                    var indices = cluster.Indices;

                    if (indices.Count == 0)
                    {
                        continue;
                    }

                    var mats = geo.MaterialIndices;

                    var ok = false;

                    int noIndexSentine = int.MaxValue;

                    countOutIndices.Clear();
                    indexOutIndices.Clear();
                    outIndices.Clear();

                    foreach (var index in indices)
                    {
                        var outIdx = geo.ToOutputVertexIndex((uint)index);
                        var count = outIdx.Count;
                        // ToOutputVertexIndex only returns NULL if index is out of bounds
                        // which should never happen
                        Debug.Assert(outIdx.Count > 0);

                        indexOutIndices.Add(noIndexSentine);
                        countOutIndices.Add(0);

                        for (int i = 0; i < count; i++)
                        {
                            if (noMatCheck || mats[(int)geo.FaceForVertexIndex((uint)outIdx.Array[i+outIdx.Offset])] == materialIndex)
                            {
                                if (indexOutIndices[indexOutIndices.Count] == noIndexSentine)
                                {
                                    indexOutIndices[indexOutIndices.Count] = outIndices.Count;
                                }
                                if (noMatCheck)
                                {
                                    outIndices.Add((int)outIdx.Array[i+outIdx.Offset]);
                                }
                                else
                                {
                                    int it;
                                    for (it = 0; it < outputVertStartIndices.Length; it++)
                                    {
                                        if (outIdx.Array[i+outIdx.Offset] == outputVertStartIndices[it])
                                        {
                                            break;
                                        }
                                    }
                                    outIndices.Add(it);
                                }
                                countOutIndices[countOutIndices.Count] += 1;
                                ok = true;
                            }
                        }
                    }

                    // if we found at least one, generate the output bones
                    // XXX this could be heavily simplified by collecting the bone
                    // data in a single step.
                    if (ok)
                    {
                        ConvertCluster(bones, model, cluster, outIndices.ToArray(), indexOutIndices.ToArray(),
                            countOutIndices.ToArray(), nodeGlobalTransform);
                    }
                }
            }
            catch (Exception e)
            {
                bones.Clear();
                throw (e);
            }
            if (bones.Count == 0)
            {
                return;
            }

            result.Bones = bones.ToArray();
            result.NumBones = bones.Count;
        }