Beispiel #1
0
            public void Initialize(Model model, VisualScene scene, bool addBinormals = true, bool addTangents = true)
            {
                PrimitiveData data = null;

                if (_rig != null)
                {
                    if (_geoEntry != null)
                    {
                        data = DecodePrimitivesWeighted(scene, _bindMatrix, _geoEntry, _rig);
                    }
                    else if (_morphController != null)
                    {
                        data = DecodeMorphedPrimitivesWeighted(scene, _bindMatrix, _morphController, _rig);
                    }
                    else
                    {
                        throw new InvalidOperationException("No valid geometry or morph controller entry for object.");
                    }
                }
                else
                {
                    if (_geoEntry != null)
                    {
                        data = DecodePrimitivesUnweighted(_bindMatrix, _geoEntry);
                    }
                    else if (_morphController != null)
                    {
                        data = DecodeMorphedPrimitivesUnweighted(_bindMatrix, _morphController);
                    }
                    else
                    {
                        throw new InvalidOperationException("No valid geometry or morph controller entry for object.");
                    }
                }

                if (data == null)
                {
                    //Something went wrong and the mesh couldn't be created
                    return;
                }

                if (addBinormals || addTangents)
                {
                    data.GenerateBinormalTangentBuffers(0, 0, addBinormals, addTangents);
                }

                Material material = null;

                //var instanceMats = _inst?.BindMaterialElement?.TechniqueCommonElement?.InstanceMaterialElements;
                //if (instanceMats != null && instanceMats.Length > 0)
                //{
                //    var instanceMat = instanceMats[0];
                //    var colladaMaterial = instanceMat?.Target?.GetElement<LibraryMaterials.Material>(scene.Root);
                //    if (colladaMaterial != null)
                //        material = CreateMaterial(colladaMaterial);
                //}

                model.Children.Add(new SubMesh(_node.Name ?? _node.ID ?? _node.SID, data, material));
            }
        public static PrimitiveData DecodeMorphedPrimitivesWeighted(VisualScene scene, Matrix4 bindMatrix, Morph morphController, Skin skin)
        {
            Matrix4 bindShapeMatrix = skin.BindShapeMatrixElement?.StringContent?.Value ?? Matrix4.Identity;

            InfluenceDef[] infList = CreateInfluences(skin, scene);

            return(null);
        }
        static PrimitiveData DecodePrimitivesWeighted(
            VisualScene scene,
            Matrix4 bindMatrix,
            Geometry geo,
            Skin skin)
        {
            Matrix4 bindShapeMatrix = skin.BindShapeMatrixElement?.StringContent?.Value ?? Matrix4.Identity;

            InfluenceDef[] infList = CreateInfluences(skin, scene);
            DecodePrimitives(geo, bindMatrix * bindShapeMatrix, infList,
                             out VertexShaderDesc info, out List <VertexPrimitive> lines, out List <VertexPolygon> faces);
            return(CreateData(info, lines, faces));
        }
        public static InfluenceDef[] CreateInfluences(Skin skin, VisualScene scene)
        {
            Bone[] boneList;
            Bone   bone = null;
            int    boneCount;

            var joints     = skin.JointsElement;
            var influences = skin.VertexWeightsElement;
            var boneCounts = influences.BoneCountsElement;
            var prims      = influences.PrimitiveIndicesElement;

            InfluenceDef[] infList = new InfluenceDef[influences.Count];

            //Find joint source
            string[] jointSIDs = null;
            foreach (InputUnshared inp in joints.GetChildren <InputUnshared>())
            {
                if (inp.CommonSemanticType == ESemantic.JOINT && inp.Source.GetElement(inp.Root) is Source src)
                {
                    jointSIDs = src.GetChild <NameArray>().StringContent.Values;
                    break;
                }
            }

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

            //Populate bone list
            boneCount = jointSIDs.Length;
            boneList  = new Bone[boneCount];
            for (int i = 0; i < boneCount; i++)
            {
                string sid  = jointSIDs[i];
                var    node = scene.FindNode(sid);

                if (node != null && node.UserData is Bone b)
                {
                    boneList[i] = b;
                }
                else
                {
                    WriteLine(string.Format("Bone '{0}' not found", sid));
                }
            }

            //Build input command list
            float[] pWeights = null;
            byte[]  pCmd     = new byte[influences.InputElements.Length];
            foreach (InputShared inp in influences.InputElements)
            {
                switch (inp.CommonSemanticType)
                {
                case ESemantic.JOINT:
                    pCmd[inp.Offset] = 1;
                    break;

                case ESemantic.WEIGHT:
                    pCmd[inp.Offset] = 2;

                    Source src = inp.Source.GetElement <Source>(inp.Root);
                    pWeights = src.GetArrayElement <FloatArray>().StringContent.Values;

                    break;

                default:
                    pCmd[inp.Offset] = 0;
                    break;
                }
            }

            float weight = 0;

            int[] boneIndices = boneCounts.StringContent.Values;
            int[] primIndices = prims.StringContent.Values;
            for (int i = 0, primIndex = 0; i < influences.Count; i++)
            {
                InfluenceDef inf = new InfluenceDef();
                for (int boneIndex = 0; boneIndex < boneIndices[i]; boneIndex++)
                {
                    for (int cmd = 0; cmd < pCmd.Length; cmd++, primIndex++)
                    {
                        int index = primIndices[primIndex];
                        switch (pCmd[cmd])
                        {
                        case 1:     //JOINT
                            bone = boneList[index];
                            break;

                        case 2:     //WEIGHT
                            weight = pWeights[index];
                            break;
                        }
                    }
                    inf.AddWeight(new BoneWeight(bone.Name, weight));
                }
                inf.Normalize();
                infList[i] = inf;
            }
            return(infList);
        }
        private void CreateRoot(ModelFile model)
        {
            Root        = new Root();
            Scene       = new VisualScene() { ID= "VisualScene-1", Name= "VisualScene-1" };
            Materials   = new Dictionary<string, Material>();
            Bitmaps     = new Dictionary<string, BitmapTexture>();
            Bones       = new List<VisualNode>();

            var no      = 0;

            // ボーン
            foreach(var i in model.Bones)
                CreateBone(i, no++);

            // マテリアル
            foreach(var i in model.Materials)
                CreateMaterial(i);

            // メッシュ
            CreateMesh(model);

            Root.Scenes.Add(Scene);
        }