protected bool ExtractSkeletonData(Entity entity, out int boneCount, out int weightCount)
        {
            bool isValidData = false;

            boneCount   = 0;
            weightCount = 0;

            //Check if we have pose animation which the HS sub render state does not
            //know how to handle
            bool hasVertexAnim = entity.Mesh.HasVertexAnimation;

            //gather data on the skeleton
            if (!hasVertexAnim && entity.HasSkeleton)
            {
                //get weights count
                Mesh mesh = entity.Mesh;
                //              nb: OGRE source gets ..blendIndexToBoneIndexMap.Count, is this accurate?
                boneCount = mesh.BoneAssignmentList.Count;

                int totalMeshes = mesh.SubMeshCount;
                for (int i = 0; i < totalMeshes; i++)
                {
                    var     ro      = new RenderOperation();
                    SubMesh subMesh = mesh.GetSubMesh(i);
                    subMesh.GetRenderOperation(ro, 0);

                    //get the largest bone assignment
                    if (boneCount > subMesh.BoneAssignmentList.Count)
                    {
                    }
                    else
                    {
                        boneCount = subMesh.BoneAssignmentList.Count;
                    }

                    //go over vertex decleration
                    //check that they have blend indices and blend weights
                    VertexElement declWeights =
                        ro.vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.BlendWeights, 0);
                    VertexElement declIndexes =
                        ro.vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.BlendIndices, 0);
                    if ((declWeights != null) && (declIndexes != null))
                    {
                        isValidData = true;
                        switch (declWeights.Type)
                        {
                        case VertexElementType.Float1:
                            weightCount = Axiom.Math.Utility.Clamp(weightCount, weightCount, 1);
                            break;

                        case VertexElementType.Float2:
                            weightCount = Axiom.Math.Utility.Clamp(weightCount, weightCount, 2);
                            break;

                        case VertexElementType.Float3:
                            weightCount = Axiom.Math.Utility.Clamp(weightCount, weightCount, 3);
                            break;

                        case VertexElementType.Float4:
                            weightCount = Axiom.Math.Utility.Clamp(weightCount, weightCount, 4);
                            break;

                        default:
                            isValidData = false;
                            break;
                        }
                        if (isValidData == false)
                        {
                            break;
                        }
                    }
                }
            }
            return(isValidData);
        }
示例#2
0
        protected XmlElement WriteSubmesh(SubMesh subMesh)
        {
            XmlElement   node = document.CreateElement("submesh");
            XmlAttribute attr;

            attr       = document.CreateAttribute("material");
            attr.Value = subMesh.MaterialName;
            node.Attributes.Append(attr);

            attr       = document.CreateAttribute("usesharedvertices");
            attr.Value = (subMesh.useSharedVertices) ? "true" : "false";
            node.Attributes.Append(attr);

            VertexData vertexData =
                (subMesh.useSharedVertices) ? mesh.SharedVertexData : subMesh.vertexData;
            IndexType indexType = IndexType.Size16;

            if (vertexData.vertexCount > short.MaxValue)
            {
                indexType = IndexType.Size32;
            }

            attr       = document.CreateAttribute("use32bitindexes");
            attr.Value = (indexType == IndexType.Size32) ? "true" : "false";
            node.Attributes.Append(attr);

            bool isTriList = true;

            // TODO: Support things other than triangle lists
            attr = document.CreateAttribute("operationtype");
            RenderOperation op = new RenderOperation();

            subMesh.GetRenderOperation(op);
            switch (op.operationType)
            {
            case OperationType.TriangleList:
                attr.Value = "triangle_list";
                break;

            case OperationType.TriangleStrip:
                attr.Value = "triangle_strip";
                isTriList  = false;
                break;

            case OperationType.TriangleFan:
                attr.Value = "triangle_fan";
                isTriList  = false;
                break;

            default:
                throw new AxiomException("Export of non triangle lists is not supported");
            }
            node.Attributes.Append(attr);

            XmlElement childNode;


            childNode = WriteFaces(subMesh, indexType, isTriList);
            node.AppendChild(childNode);

            if (!subMesh.useSharedVertices)
            {
                childNode = WriteGeometry(subMesh);
                node.AppendChild(childNode);
            }

            if (subMesh.BoneAssignmentList.Count > 0)
            {
                childNode = WriteBoneAssignments(subMesh);
                node.AppendChild(childNode);
            }

            return(node);
        }