Esempio n. 1
0
        public static MeshData[] ProcMesh(FbxManager manager, FbxNode node, FbxMesh mesh, ImportOptions importOptions, Matrix4 additionalTransform)
        {
            var transform = additionalTransform * FbxMath.EvaluateGlobalTransform(node).ToMatrix4();

            transform = transform * FbxMath.GetGeometryOffset(node).ToMatrix4();
            var  converter = new FbxGeometryConverter(manager);
            bool success   = false;

            try
            {
                mesh    = FbxMesh.Cast(converter.Triangulate(mesh, false));                  //ToDo :? Может true? Чтобы не создавать второй mesh в Attribute
                success = true;
            }
            catch (Exception ex)
            {
                FbxImportLog.LogError(node, "Inside Triangulate error: " + ex);
            }
            if (!success || mesh == null)
            {
                return(null);
            }
            MeshData data = ReadTriangles(mesh, node);
            var      ret  = ReadMaterialsAndSplitByMaterials(data);

            foreach (var m in ret)
            {
                ReadMeshElements(m, importOptions, ref transform);
            }

            return(ret);
        }
Esempio n. 2
0
        //ToDo : учет associate model?
        // GlobalTransform of the bone at the binding moment.
        //
        // (Comments from fbxcluster.h)
        // Transformation matrices. A link has three transformation matrices:
        // - Transform refers to the global initial transform of the geometry node(geometry is the attribute of the node) that contains the link node.
        // - TransformLink refers to global initial transform of the link(bone) node.
        // - TransformAssociateModel refers to the global initial transform of the associate model.
        //
        // For example, given a mesh binding with several bones(links), Transform is the global transform
        // of the mesh at the binding moment, TransformLink is the global transform of the bone(link)
        // at the binding moment, TransformAssociateModel is the global transform of the associate model
        // at the binding moment.

        FbxAMatrix GetInitialTransform()
        {
            if (cluster == null)
            {
                return(FbxMath.EvaluateGlobalTransform(Node));
            }

            //Each cluster is associated with a FbxNode (bone)
            //cluster.GetLink().GetUniqueID() == Node.GetUniqueID();


            //??? Учитывать ли AxisSystem?
            //??? Не совсем понятны отличаи globalMeshTransform == skin.GetGeometry().GetNode().EvaluateGlobalTransform(), от cluster.GetTransformMatrix()

            //matrix associated with the geometry node containing the link. (global transform of the mesh at the binding moment)
            FbxAMatrix globalMeshInitialTransform = new FbxAMatrix();

            cluster.GetTransformMatrix(globalMeshInitialTransform);

            //Get matrix associated with the link node (bind pose,  bone transform) at the binding moment
            FbxAMatrix boneInitialTransform = new FbxAMatrix();

            cluster.GetTransformLinkMatrix(boneInitialTransform);
            //Дополнительная матрица которую cluster ассоциирует с Node - Трансформация в момент привязки.

            //bind pose matrix that is local for the mesh = Inverse(TransformMatrix) * TransformLinkMatrix
            FbxAMatrix localBindPose = (globalMeshInitialTransform.mul(geometryOffset).Inverse()).mul(boneInitialTransform);

            //globalMeshTransform * Inverse(globalMeshInitialTransform) * boneInitialTransform
            return(globalMeshTransform.mul(geometryOffset).mul(localBindPose));
        }
Esempio n. 3
0
        //const int maxNameLength = 40;

        //static void AppendName(ref string name1, string name2)
        //{
        //	if (name1.Length < maxNameLength)
        //	{
        //		name1 = name1 + " + " + name2;
        //		if (name1.Length >= maxNameLength) //no more append
        //			name1 += " + ...";
        //	}
        //}

        //void MergeGeometriesByMaterials()
        //{
        //	int mergedCount = 0;
        //	for (int i = 0; i < Geometries.Count; i++)
        //	{
        //		MeshData g1 = Geometries[i];
        //		if(g1 == null)
        //			continue;
        //		for (int j = i + 1; j < Geometries.Count; j++)
        //		{
        //			MeshData g2 = Geometries[j];
        //			if (g2 != null && g1.MaterialIndex == g2.MaterialIndex && g1.VertexComponents == g2.VertexComponents && g1.PolygonSize == g2.PolygonSize)
        //			{
        //				var newVertices = new VertexInfo[g1.Vertices.Length + g2.Vertices.Length];
        //				g1.Vertices.CopyTo(newVertices, 0);
        //				g2.Vertices.CopyTo(newVertices, g1.Vertices.Length);
        //				g1.Vertices = newVertices;
        //				g1.ClearCache(); //No longer valid
        //				AppendName(ref g1.Name, g2.Name);
        //				//m1.NormalsSource remains from first
        //				Geometries[j] = null;
        //				mergedCount++;
        //			}
        //		}
        //	}

        //	int count = Geometries.Count - mergedCount;
        //	var res = new List<MeshData>(count);
        //	for (int i = 0; i < count; i++)
        //		if (Geometries[i] != null)
        //			res.Add(Geometries[i]);
        //	Geometries = res;
        //}


        static void FillBoneAssignments(MeshData data, Skeleton skeleton)
        {
            if (skeleton == null)
            {
                for (int i = 0; i < data.Vertices.Length; i++)
                {
                    data.Vertices[i].Vertex.BlendIndices = new Vector4I(-1, -1, -1, -1);
                }
            }
            data.VertexComponents |= StandardVertex.Components.BlendIndices | StandardVertex.Components.BlendWeights;
            Dictionary <int, BoneAssignment> boneAssignments = ProcessSkeleton.GetBoneAssignments(data.Mesh, skeleton);

            if (boneAssignments != null)
            {
                for (int i = 0; i < data.Vertices.Length; i++)
                {
                    ref VertexInfo v = ref data.Vertices[i];
                    if (boneAssignments.TryGetValue(v.ControlPointIndex, out BoneAssignment ba))
                    {
                        FbxMath.ConvertBoneAssignment(ref ba, out v.Vertex.BlendIndices, out v.Vertex.BlendWeights);
                    }
                    else
                    {
                        v.Vertex.BlendIndices = new Vector4I(-1, -1, -1, -1);
                    }
                }
            }
Esempio n. 4
0
        public SkeletonBone(FbxNode boneNode, SkeletonBone parentBone, FbxSkin[] skins, SceneLoader scene)
        {
            //this.scene = scene;
            this.scene = scene;
            Node       = boneNode;
            ParentBone = parentBone;
            //animationTrackKeyFrames = new List<HashSet<double>>();
            cluster = Skeleton.FindCluster(Node, skins, out skin);               //Поиск по всем skins во всех mesh. Можно было бы сделать эффективнее.

            globalMeshTransform = new FbxAMatrix();
            globalMeshTransform.SetIdentity();
            geometryOffset = new FbxAMatrix();
            geometryOffset.SetIdentity();
            if (cluster != null)
            {
                FbxNode meshNode = skin.GetGeometry()?.GetNode();
                if (meshNode != null)
                {
                    globalMeshTransform = meshNode.EvaluateGlobalTransform(FbxExtensions.ToFbxTime(-1));                         // FbxMath.GetGlobalPosition( meshNode, FbxExtensions.ToFbxTime( -1 ), null );
                    geometryOffset      = FbxMath.GetGeometryOffset(meshNode);
                }
            }
            InitialTransform = GetInitialTransform().ToMatrix4();             //Во внешнем коде надо использовать это значение, т.к. результат GetInitialTransform() может зависеть от установленного AnimationTrack
        }