Exemplo n.º 1
0
        private Drawable TryConvertDrawable(FbxDocument fdoc, string name)
        {
            var rootnodes = fdoc.GetSceneNodes();

            var mlists   = new List <List <FbxModel> >();
            var mlistall = new List <FbxModel>();

            foreach (var node in rootnodes)
            {
                if (node.Name == "Model")
                {
                    var mlist = TryConvertModels(node); //flatten any models structure with depth >2
                    if (mlist != null)
                    {
                        mlists.Add(mlist);
                        mlistall.AddRange(mlist);
                    }
                }
            }

            var mlHigh = new List <DrawableModel>();
            var mlMed  = new List <DrawableModel>();
            var mlLow  = new List <DrawableModel>();
            var mlVlow = new List <DrawableModel>();
            var mlUnks = new List <DrawableModel>();
            var mlAll  = new List <DrawableModel>();

            foreach (var m in mlistall)
            {
                var mnl = m.Name.ToLowerInvariant();
                if (mnl.EndsWith("_vlow"))
                {
                    mlVlow.Add(m.Model);
                }
                else if (mnl.EndsWith("_low"))
                {
                    mlLow.Add(m.Model);
                }
                else if (mnl.EndsWith("_med"))
                {
                    mlMed.Add(m.Model);
                }
                else if (mnl.EndsWith("_high"))
                {
                    mlHigh.Add(m.Model);
                }
                else
                {
                    mlUnks.Add(m.Model);
                }
            }
            if (mlHigh.Count == 0)//mlUnks could be embedded collisions... ignore for now
            {
                mlHigh.AddRange(mlUnks);
            }
            mlAll.AddRange(mlHigh);
            mlAll.AddRange(mlMed);
            mlAll.AddRange(mlLow);
            mlAll.AddRange(mlVlow);



            var allVerts = new List <Vector3>();
            var bbMin    = new Vector3(float.MaxValue);
            var bbMax    = new Vector3(float.MinValue);
            var bsCen    = Vector3.Zero;
            var bsRad    = 0.0f;

            foreach (var m in mlistall)
            {
                if (m?.Model?.Geometries == null)
                {
                    continue;
                }
                foreach (var g in m.Model.Geometries)
                {
                    var vb = g.VertexData.VertexBytes;
                    var vs = g.VertexData.VertexStride;
                    var vc = g.VertexData.VertexCount;
                    for (int i = 0; i < vc; i++)
                    {
                        var vp = MetaTypes.ConvertData <Vector3>(vb, i * vs);//position offset should always be 0!
                        allVerts.Add(vp);
                        bbMin = Vector3.Min(bbMin, vp);
                        bbMax = Vector3.Max(bbMax, vp);
                        //bsCen += vp;
                    }
                }
            }
            if (allVerts.Count > 0)
            {
                //bsCen = bsCen / allVerts.Count;
                bsCen = (bbMin + bbMax) * 0.5f;
                foreach (var vp in allVerts)
                {
                    bsRad = Math.Max(bsRad, (vp - bsCen).Length());
                }
            }



            var sgrp  = new ShaderGroup();
            var slist = new List <ShaderFX>();
            var smapp = new List <ushort>();

            foreach (var m in mlAll)
            {
                if (m?.Geometries == null)
                {
                    continue;
                }
                smapp.Clear();
                foreach (var g in m.Geometries)
                {
                    smapp.Add((ushort)slist.Count);
                    slist.Add(g.Shader);
                }
                m.ShaderMapping = smapp.ToArray();//TODO: re-use shaders!!
            }
            sgrp.Shaders            = new ResourcePointerArray64 <ShaderFX>();
            sgrp.Shaders.data_items = slist.ToArray();
            sgrp.ShadersCount1      = (ushort)slist.Count;
            sgrp.ShadersCount2      = (ushort)slist.Count;
            sgrp.VFT         = 1080113376;                  //is this needed?
            sgrp.Unknown_4h  = 1;
            sgrp.Unknown_30h = (uint)(8 + slist.Count * 3); //WTF is this?


            var d = new Drawable();

            d.Name                 = name + ".#dr";
            d.ShaderGroup          = sgrp;
            d.BoundingCenter       = bsCen;
            d.BoundingSphereRadius = bsRad;
            d.BoundingBoxMin       = bbMin;
            d.BoundingBoxMax       = bbMax;
            d.LodDistHigh          = 9998;//lod dist defaults
            d.LodDistMed           = 9998;
            d.LodDistLow           = 9998;
            d.LodDistVlow          = 9998;
            d.Unknown_9Ah          = 33;//WTF is this???
            d.FileVFT              = 1079446584;
            d.FileUnknown          = 1;
            d.DrawableModels       = new DrawableModelsBlock();
            if (mlHigh.Count > 0)
            {
                d.DrawableModels.High = mlHigh.ToArray();
                d.FlagsHigh           = 1;//what flags should be used??
            }
            if (mlMed.Count > 0)
            {
                d.DrawableModels.Med = mlMed.ToArray();
                d.LodDistHigh        = bsRad * 2.0f; //when med models present, generate a high lod dist..
                d.FlagsMed           = 1;
            }
            if (mlLow.Count > 0)
            {
                d.DrawableModels.Low = mlLow.ToArray();
                d.LodDistMed         = bsRad * 8.0f; //when low models present, generate a med lod dist..
                d.FlagsLow           = 1;
            }
            if (mlVlow.Count > 0)
            {
                d.DrawableModels.VLow = mlVlow.ToArray();
                d.LodDistLow          = bsRad * 32.0f; //when vlow models present, generate a low lod dist..
                d.FlagsVlow           = 1;
            }

            d.BuildRenderMasks();

            d.LightAttributes = new ResourceSimpleList64_s <LightAttributes_s>();
            //todo: light attributes?


            return(d);
        }